<?php

	require_once(dirname(__FILE__).'/class.adminview.php');

	class AKB_QUESTION extends AdminView
	{
		var $questions = array();
		var $cats = array();
		var $comments = array();
		var $commentInfo = array();
		var $query = '';
		var $countQuery = '';
		var $attachmentDirectory = '';
		var $importFile = '';
		var $importFields = array (
			'title',
			'answer',
			'metakeywords',
			'metadescription',
			'sortorder',
			'visible',
			'detectrelated',
		);

		var $defaultTableSort = "lastupdated";

		/**
		* AKB_QUESTION
		* Constructor for the class
		*
		* @return void
		*/
		function AKB_QUESTION()
		{
			$this->attachmentDirectory = realpath(dirname(__FILE__).'/../../../attachments');
			$this->importFile = $this->attachmentDirectory.DIRECTORY_SEPARATOR.'import.csv';
		}

		/**
		* HandlePage
		*
		* Handles page routing based on the current ToDo get string
		* @return void
		*/
		function HandlePage()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')
			&& !$_SESSION['user']->verify('question', 'approve')
			&& !$_SESSION['user']->verify('question', 'review')) {
				$this->NoPermission();
				return;
			}

			if (isset($_GET['ToDo'])) {
				switch (strtolower($_GET['ToDo'])) {
					case 'reviewsubmittedquestions':
						if (isset($_POST['bulkaction'])) {
							$this->SubmittedQuestionBulkAction();
						}
						$this->ShowSubmittedQuestionList();
					break;
					case 'viewworkflowquestions':
						if (isset($_GET['letter'])) {
							$_GET['wfletter'] = $_GET['letter'];
						}
						
						if (isset($_POST['bulkaction'])) {
							$this->BulkAction();
						}

						$this->ShowWorkflowQuestionList();
					break;
					case 'sendapprovalemail':
						$this->sendApprovalEmail();
					break;
					case 'viewquestions':
					default:
						if (isset($_POST['bulkaction'])) {
							$this->BulkAction();
						}
						$this->ShowQuestionList();
				}
			}
		}
		
		/**
		* GetWorkFlowStatusOptions
		* Get html options for displaying comment statuses
		*
		* @param string $cur the current status
		*
		* @return string the html for the options
		*/
		function GetStatusOptions($cur, $showAll = false, $width=308)
		{
			$onChange = (isset($GLOBALS['statusOnchange'])) ? $GLOBALS['statusOnchange']:'';
			$str = '<select name="workflowstatus" id="workflowstatus" class="Field'.$width.'" '.$onChange.'>';
			
			if ($showAll) {
				$status[] = GetLang('AllStatuses');
			}
			
			$status[] = WF_STATUS_APPROVED;
			$status[] = WF_STATUS_REPENDING;
			$status[] = WF_STATUS_DISAPPROVED;

			if (AKB_AUTH::IsSuperAdmin() || $showAll) {
				$status[] = WF_STATUS_AUTO_APPROVED;
		}
		
		foreach ($status as $s) {
				$langStr = decodeWorkflowStatus($s);
				if ($langStr == '') {
					$langStr = $s;
				}
		
				if (isset($_GET['questionid']) && $cur == WF_STATUS_DISAPPROVED && isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && !$this->HasQuestionApprovalEditPerm($_GET['questionid'], WF_STATUS_DISAPPROVED) && $s== WF_STATUS_APPROVED) {} else {
				$str .= '<option value="'.$s.'"'.(($cur == $s || ($s == WF_STATUS_REPENDING && $cur == WF_STATUS_PENDING)) ? ' selected' : '').'>'.$langStr.'</option>';
				}
			}
			
			$str .= '</select>';

			return $str;
		}
		
		/**
		* UpdateStatus
		* Update the status of an article
		*
		* @return boolean
		*/
		function UpdateStatus($questionId, $status, $emailSubject = '', $emailBody = '', $skipEmail = true)
		{  
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return false;
			}

			$newStatus = "";
			$msg = "";

			if (isset($questionId) && isset($status) && validUrl()) {
				$questionIdArray = explode('_', $questionId);
				foreach ($questionIdArray as $questionId) {
					$q = new API_QUESTION();
					$q->load($questionId);
					
					switch ($status) {
						case WF_STATUS_APPROVED:
							$_POST['workflowstatus'] = WF_STATUS_APPROVED;
							$msg = GetLang("ArticleApproved");
							break;
						case WF_STATUS_AUTO_APPROVED:
							$_POST['workflowstatus'] = WF_STATUS_AUTO_APPROVED;
							$msg = GetLang("ArticleApproved");
							break;
						case WF_STATUS_DISAPPROVED:
							$_POST['workflowstatus'] = WF_STATUS_DISAPPROVED;
							$msg = GetLang("ArticleDisapproved");
							break;
					}
					
					if ($_POST['workflowstatus'] == WF_STATUS_AUTO_APPROVED || $_POST['workflowstatus'] == WF_STATUS_APPROVED) {
						$cats = $q->get_category_associations($questionId);
						
						// Save the category associations history
						$query = sprintf("delete from %scatassoc_history where questionid='%d'", $GLOBALS['tablePrefix'], $questionId);
						$GLOBALS['AKB_DB']->Query($query);
			
						for ($i = 0; $i < sizeof($cats); $i++) {
							$query = sprintf("insert into %scatassoc_history(categoryid, questionid) values(%d, %d)", $GLOBALS['tablePrefix'], $cats[$i], $questionId);
							$GLOBALS['AKB_DB']->Query($query);
						}
					}
					
					if (!$skipEmail && isset($q->userid)) {
						// Get the author's details
						$author = new API_USER();
						$author->load($q->userid);
						
						$emailBodyElements['articletitle'] = $q->title;
						$emailBodyElements['firstname'] = $author->firstname;
						$emailBodyElements['lastname'] = $author->lastname;
						$emailBodyElements['username'] = $author->username;
						$emailBodyElements['articlelink'] = GetUrl('question', $q->questionid);
						$emailBodyCopy = $emailBody;
						$matches = array();
						preg_match_all('/(?siU)(%%[a-zA-Z0-9_]{1,}%%)/', $emailBodyCopy, $matches);
						foreach ($matches[0] as $key=>$val) {
							$pattern1 = $val;
							$pattern2 = str_replace('%', '', $pattern1);
							$emailBodyCopy = str_replace($pattern1, @$emailBodyElements[$pattern2], $emailBodyCopy);
						}
						$email = new Email_API();
						setEmailVars($email);
						$email->Set('CharSet', $GLOBALS['charset']);
						$email->From($GLOBALS['contactEmail']);
						$email->Set('Subject', $emailSubject);
						$email->AddBody('text', $emailBodyCopy);
						$email->AddRecipient($author->email, '', 'h');
						$email_result = $email->Send();
						if (!$email_result) {
							return false;
						}
					}
					if (!$q->save()) {
						return false;
					}
				}
				return true;
			}
			return false;
		}

		/**
		* BulkAction
		*
		* The handler for performing an action to multiple items
		* @return void
		*/
		function BulkAction() {
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')
			&& !$_SESSION['user']->verify('question', 'review')) {
				$this->NoPermission();
				return;
			}

			if (!isset($_POST['bulkaction'])) {
				return false;
			}

			if (!isset($_POST['item']) || !is_array($_POST['item'])) {
				return false;
			}

			if (empty($_POST['item'])) {
				return false;
			}

			$q = new API_QUESTION();
			switch (strtolower($_POST['bulkaction'])) {
				case 'resetviews':
					if ($_SESSION['user']->verify('question', 'edit')) {
						if ($q->multiUpdateField('views', '0', $_POST['item'])) {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiResetViewsOk'), MSG_SUCCESS);
						} else {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiResetViewsFail'), MSG_SUCCESS);
						}
					} else {
						$this->NoPermission();
						return false;
					}
				break;
				case 'resetrating':
					if ($_SESSION['user']->verify('question', 'edit')) {
						if ($q->multiUpdateField('negvotes', '0', $_POST['item'])
						&& $q->multiUpdateField('posvotes', '0', $_POST['item'])) {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiResetRatingsOk'), MSG_SUCCESS);
						} else {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiResetRatingsFail'), MSG_SUCCESS);
						}
						$qids = array_map(array($GLOBALS['AKB_DB'], 'Quote'), array_keys($_POST['item']));

						$query = "DELETE FROM ".$GLOBALS['tablePrefix']."ratings
						WHERE questionid IN (".implode(',', $qids).")";
						$GLOBALS['AKB_DB']->Query($query);
					} else {
						$this->NoPermission();
						return false;
					}
				break;
				case 'delete':
					if ($_SESSION['user']->verify('question', 'delete')) {
						if ($q->multiDelete($_POST['item'])) {
							$query = "DELETE FROM ".$GLOBALS['tablePrefix']."categoryassociations
							WHERE questionid IN (".implode(',', array_keys($_POST['item'])).")";
							$GLOBALS['AKB_DB']->Query($query);
							$query = "DELETE FROM ".$GLOBALS['tablePrefix']."catassoc_history
							WHERE questionid IN (".implode(',', array_keys($_POST['item'])).")";
							$GLOBALS['AKB_DB']->Query($query);
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiDeleteOk'), MSG_SUCCESS);
						} else {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiDeleteFail'), MSG_ERROR);
						}
					} else {
						$this->NoPermission();
						return false;
					}
				break;
			}
		}

		/**
		* SubmittedQuestionBulkAction
		*
		* The handler for performing an action to multiple items
		* @return boolean returns false if anything goes wrong
		*/
		function SubmittedQuestionBulkAction()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')
			&& !$_SESSION['user']->verify('question', 'review')) {
				$this->NoPermission();
				return;
			}

			if (!isset($_POST['bulkaction'])) {
				return false;
			}

			if (!isset($_POST['item']) || !is_array($_POST['item'])) {
				return false;
			}

			if (empty($_POST['item'])) {
				return false;
			}

			foreach ($_POST['item'] as $key => $val) {
				if (!is_numeric($key)) {
					return false;
				}
			}

			switch (strtolower($_POST['bulkaction'])) {
				case 'delete':
					if ($_SESSION['user']->verify('question', 'review')) {
						$query = "DELETE FROM
						".$GLOBALS['tablePrefix']."submittedquestions
						WHERE subquestid IN (".implode(',', array_keys($_POST['item'])).")";
						if ($GLOBALS['AKB_DB']->Query($query)) {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiDeleteOk'), MSG_SUCCESS);
						} else {
							$GLOBALS['Message'] = MessageBox(GetLang('QuestionMultiDeleteFail'), MSG_ERROR);
						}
					} else {
						$this->NoPermission();
						return false;
					}
				break;
			}
		}

		/**
		* PreviewQuestion
		* Shows the question preview popup
		*
		* @return void
		*/
		function PreviewQuestion()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')) {
				$this->NoPermission();
				return;
			}

			// Preview a question
			$GLOBALS["Question"] = '<script type="text/javascript" language="javascript">document.write(window.opener.document.frmPreview.q.value);</script>';
			$GLOBALS["Answer"] = '<script type="text/javascript" lanugage="javascript">document.write(window.opener.document.frmPreview.a.value);</script>';
			$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("question.preview");
			$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
		}

		/**
		* SaveNewQuestion
		* Save a newly created question and display any feeback
		*
		* @return new questionid
		*/
		function SaveNewQuestion($versioned=true)
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}
			
			// Check if a category is selected
			if (!isset($_POST['category']) || (sizeof($_POST['category']) == 1 and $_POST['category'][0] == '0')) {
				return ;
			}

			// Build the query to add the question
			if (isset($_POST['questionsrelated'])
				&& is_array($_POST['questionsrelated'])) {
				$_POST['related'] = implode(', ', $_POST['questionsrelated']);
			} else {
				$_POST['related'] = '';
			}
			$_POST['detectrelated']	= isset($_POST['detectrelated']) ? 1 : 0;
			$_POST['workflowstatus']	= WF_STATUS_AUTO_APPROVED;
			$_POST['answer']		= $_POST['wysiwyg_html'];
			$_POST['userid']		= $_SESSION['user']->userid;
			$_POST['views']			= 0;
			$_POST['posvotes']		= 0;
			$_POST['negvotes']		= 0;
			$_POST['score']			= 0;
			$_POST['emailed']		= 0;

			// check expiry
			if (isset($_POST["expires"]) && $_POST["expires"] == "on") {
				$_POST["enableexpiry"] = 1;
			} else {
				$_POST["enableexpiry"] = 0;
			}

			// start date
			$_POST["startdate"] = sprintf("%s-%s-%s %s", $_POST["startyear"],
				$_POST["startmonth"], $_POST["startday"], date('H:i:s',strtotime($_POST['starttime'])));

			// expiry date
			if ($_POST["enableexpiry"] == 1) {
				$_POST["expirydate"] = sprintf("%s-%s-%s %s", $_POST["endyear"],
					$_POST["endmonth"], $_POST["endday"], date('H:i:s',strtotime($_POST['endtime'])));
			} else {
				$_POST["expirydate"] = $_POST["startdate"];
			}

			if ($_SESSION['user']->verify('question', 'approve') && isset($_POST['visible']) && strtolower($_POST['visible']) == 'on') {
				$_POST['visible'] = 1;
			} else {
				$_POST['visible'] = 0;
			}
			
			// ----- Workflow logic part 1 -----
			$in_grp_ids = '';
			$approval_users = array();
			$users_added = array();
			$num_approval_users = 0;
			$totalCategories = array();
			$totalCategoriesNames = '';
			$continue = true;

			if (validUrl()) {
				if (isset($_POST['category']) && is_array($_POST['category']) && sizeof($_POST['category'])) {
					$categoryQueryString = "'" . implode("','", $_POST['category']) . "'";
					$query = sprintf("select categoryid, name, approvaltype from %scategories where categoryid in (%s) and (approvaltype = '%d' OR  approvaltype = '%d' )", $GLOBALS['tablePrefix'], $categoryQueryString, CATEGORIES_ALWAYS_APPROVAL, CATEGORIES_ONCE_APPROVAL);
					$result = $GLOBALS['AKB_DB']->Query($query);
					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$totalCategories['ids'][$row['categoryid']] = $row['categoryid'];
						$totalCategories['names'][$row['name']] = $row['name'];
					}
				}
			}
			
			if(isset($totalCategories['ids']) && $_SESSION['user']->userid != 1) {
				// Get all the available groups
				$query = sprintf('SELECT groupid, name FROM %sgroups ORDER BY name ASC', $GLOBALS['tablePrefix']);
				$result = $GLOBALS['AKB_DB']->Query($query);
				$validGroups = array();
				while($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					$group = new API_GROUP();
					$groupid = $row['groupid'];
					$group->load($groupid);
					
					$groupPerm = $group->perms;
					if (isset($groupPerm['question']['edit']) && $groupPerm['question']['edit'] == '1'
					&& isset($groupPerm['category']['approve']) && $groupPerm['category']['approve'] == '1'
					) {
						if (((is_array($group->applies['category']) && 
						array_intersect($totalCategories['ids'], $group->applies['category'])) || $group->applies['category'] == 'all') && $group->applies['feonly'] != '1') {
							$validGroups[] = $groupid;
						}
					}
				}
				$in_grp_ids = "'" . implode("','", $validGroups) . "'";
				
				// Do any of the categories selected require approval befoer publishing?
				$query = sprintf("SELECT DISTINCT u.userid, u.firstname, u.lastname, u.username, u.email
									FROM %smembers m, %susers u
									WHERE m.userid = u.userid
									AND m.groupid IN (%s)
				", $GLOBALS['tablePrefix'], $GLOBALS['tablePrefix'], $in_grp_ids);
				$totalCategoriesNames = "\n\n* " .implode("\n* ", $totalCategories['names']);
				if (sizeof($totalCategories['names']) == 1) {
					$totalCategoriesNames = "\n\n* " . array_pop($totalCategories['names']);
				}
				
				$result = $GLOBALS['AKB_DB']->Query($query);
				$num_approval_users = $GLOBALS['AKB_DB']->CountResult($query);
				if($num_approval_users > 0) {
					// This article requires approval before publishing
					$_POST['workflowstatus'] = WF_STATUS_PENDING;

					while($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						if ($row['userid'] == $_SESSION['user']->userid) {
							$continue = false;
							$_POST['workflowstatus'] = WF_STATUS_APPROVED;
						}
						if(!in_array($row['email'], $users_added)) {
							array_push($approval_users, $row);
							array_push($users_added, $row['email']);
						}
					}
				}
			}
			if (isset($_POST['featured']) && $_POST['featured'] == '1') {
				$_POST['featured'] = 1;
			} else {
				$_POST['featured'] = 0;
			}

			$question = new API_QUESTION();
			$question->versioned = $versioned;
			$GLOBALS['newid'] = $question->create();

			if ($_POST['restrict'] == 1) {
				// We need to save groups
				$query = sprintf("delete from %squestion_auth where questionid='%d'", $GLOBALS['tablePrefix'], $_POST['questionid']);
				$GLOBALS['AKB_DB']->Query($query);

				if ((isset($_POST['groups'])) && (is_array($_POST['groups']))) {
					for ($i = 0; $i < sizeof($_POST['groups']); $i++) {
						$query = sprintf("insert into %squestion_auth(questionid, groupid) values(%d, %d)", $GLOBALS['tablePrefix'], $GLOBALS['newid'], $_POST['groups'][$i]);
						$GLOBALS['AKB_DB']->Query($query);
					}
				}
			}

			// Save the category associations
			foreach ($_POST['category'] as $catid) {
				if ($catid > 0 && $GLOBALS['newid']) {
					$query = sprintf("insert into %scategoryassociations(categoryid, questionid) values(%d, %d)", $GLOBALS["tablePrefix"], $catid, $GLOBALS['newid']);
					$GLOBALS['AKB_DB']->Query($query);
					if ($_POST['workflowstatus'] == WF_STATUS_APPROVED || $_POST['workflowstatus'] == WF_STATUS_AUTO_APPROVED) {
						$query = sprintf("insert into %scatassoc_history(categoryid, questionid) values(%d, %d)", $GLOBALS["tablePrefix"], $catid, $GLOBALS['newid']);
						$GLOBALS['AKB_DB']->Query($query);
					}
				}
			}

			// Work with the attachments
			$this->SaveAttachments($GLOBALS['newid']);

			// Do we need to delete a user submitted question that was used to
			// create this question?
			if (isset($_POST['sQuestId'])) {
				$subquest = new API_SUBMITTEDQUESTION();
				$subquest->load((int)$_POST['sQuestId']);

				if ($subquest->loaded) {

					// Send the submitter of the question an email if the user
					// says to and the question is visible
					if (isset($_POST['emailtosubmitter'])
						&& $_POST['emailtosubmitter'] == 1
						&& $_POST['visible'] == 1
						&& ($_POST['workflowstatus'] == WF_STATUS_AUTO_APPROVED || $_POST['workflowstatus']	== WF_STATUS_APPROVED)
						) {
						$this->NotifySubmitterNewQuestion($subquest, $GLOBALS['newid']);
					}
					$subquest->delete($_POST['sQuestId']);
				}
			}
			
			// ----- Workflow logic part 2 -----
			if($num_approval_users > 0 && $continue && validUrl()) {
				foreach($approval_users as $approval_user) {
					// Send the approval emails out
					$name = $approval_user['username'];
					if (trim($approval_user['firstname']) != '' || trim($approval_user['lastname']) != '') {
						$name = trim($approval_user['firstname']) . ' ' . trim($approval_user['lastname']);
					}
					$message = sprintf(GetLang('ApprovalArticleMessage'), $name,"\n\n", $totalCategoriesNames,"\n\n", $GLOBALS['pathToKB'], $GLOBALS['newid'], 1);
					$email = new Email_API();
					setEmailVars($email);
					$email->Set('CharSet', $GLOBALS['charset']);
					$email->From($GLOBALS['contactEmail']);
					$email->Set('Subject', GetLang('ApprovalArticleSubject'));
					$email->AddBody('text', $message);
					$email->AddRecipient($approval_user['email'], '', 'h');
					$email_result = $email->Send();
				}
				// Change the success message
				$GLOBALS['SuccessMesg'] = 'QuestionSavedNewRequiresApproval';
			}
			else {
				$GLOBALS['SuccessMesg'] = 'QuestionSavedNew';
			}
			$this->saveCustomFields((int)$GLOBALS['newid']);
			return $GLOBALS['newid'];
		}

		/**
		* GetWYSIWYGEditor
		* Get the WYSIWYG field
		*
		* @param string $Content the content to display
		* @return string The html for the editor
		*/
		function GetWYSIWYGEditor($Content = "",$width="100%",$height="300")
		{
			// Output the WYSIWYG HTML editing component
			// $SpanId is the id of the tooltip to show for help
			ob_start();

			if ($GLOBALS["useWYSIWYGEditor"] == true && is_file(dirname(__FILE__).'/../../de/class.devedit.php')) {
				// Workout the image/flash directory path
				$parts = parse_url($GLOBALS['pathToKB'].'/images');
				$path = $parts['path'];

				//Include the DevEdit class file
				include_once(dirname(__FILE__).'/../../de/class.devedit.php');

				// Create a new DevEdit class object
				$myDE = new DevEdit();

				// Set the name of this DevEdit class
				$myDE->SetName("wysiwyg");

				// Set the path to the de folder
				SetDevEditPath("de");

				// Set the path to the folder that contains the flash files for the flash manager
				$myDE->SetFlashPath($path);
				$myDE->SetMediaPath($path);
				$myDE->SetLinkPath($path);

				if ($GLOBALS['charset'] == 'utf-8') {
					$myDE->DisableHTMLEntities();
				}

				//If you want to use the spell checker, then you can set
				//the spelling language to DE_AMERICAN, DE_BRITISH or DE_CANADIAN,
				//DE_FRENCH, DE_SPANISH, DE_GERMAN, DE_ITALIAN, DE_PORTUGESE,
				//DE_DUTCH, DE_NORWEGIAN, DE_SWEDISH or DE_DANISH
				$myDE->SetLanguage(DE_AMERICAN);

				//How do we want images to be inserted into our HTML content?
				//DE_PATH_TYPE_FULL will insert a image in this format: http://www.mysite.com/test.html
				//DE_PATH_TYPE_ABSOLUTE will insert a image in this format: /myimage.gif
				$myDE->SetPathType(DE_PATH_TYPE_FULL);

				//Are we editing a full HTML page, or just a snippet of HTML?
				//DE_DOC_TYPE_HTML_PAGE means we're editing a complete HTML page
				//DE_DOC_TYPE_SNIPPET means we're editing a snippet of HTML
				$myDE->SetDocumentType(DE_DOC_TYPE_SNIPPET);

				//Do we want images to appear in the image manager as thumbnails or just in rows?
				//DE_IMAGE_TYPE_ROW means just list in a tabular format, without a thumbnail
				//DE_IMAGE_TYPE_THUMBNAIL means list in 4-per-line thumbnail mode
				$myDE->SetImageDisplayType(DE_IMAGE_TYPE_ROW);

				//Do we want flash files to appear in the flash manager as thumbnails or just in rows?
				//DE_FLASH_TYPE_ROW means just list in a tabular format, without a thumbnail
				//DE_FLASH_TYPE_THUMBNAIL means list in 4-per-line thumbnail mode
				$myDE->SetFlashDisplayType(DE_FLASH_TYPE_ROW);

				// Always clear ms word tags from the code
				$myDE->ForcePasteWord();

				//Show table guidelines as dashed
				$myDE->EnableGuidelines();

				// Set the content
				$myDE->SetValue($Content);

				// Set the default wysiwyg mode - after the intial load the mode
				// is determined from a cookie
				$myDE->SetDevEditMode("Simple");

				// Disable the preview tab
				$myDE->DisablePreviewMode();

				// Setup the toolbars
				$myDE->AddToolbarButton("Insert Image", 57, 20, $GLOBALS["pathToKB"]."/admin/images/image_toolbaricon.gif", "wysiwyg.commands.getCommand('Image').execute();", "Simple");
				$myDE->AddToolbarButton("Insert Image", 57, 20, $GLOBALS["pathToKB"]."/admin/images/image_toolbaricon.gif", "wysiwyg.commands.getCommand('Image').execute();", "Complete");

				$rows = array (
					"Fullscreen,Paste,Findreplace,Spellcheck,-,Bold,Underline,Italic,-,OrderedList,UnorderedList,-,JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,-,CreateLink",
					"Fontname,Fontsize,-,Fontcolor,Highlight,-,Insert Image,Flash,Media,-,Table,-,Help",
				);
				$myDE->AddToolbar("Simple", implode(",|,", $rows));

				$rows = array (
					"Fullscreen,Paste,Findreplace,Spellcheck,Bold,Underline,Italic,Strikthrough,-,OrderedList,UnorderedList,-,JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,Help",
					"Spellcheck,-,RemoveFormat,-,Indent,Outdent,-,SubScript,SuperScript,CreateLink,CreateEmailLink,Anchor,-,Insert Image,Flash,Media,-,Table,Form",
					"Fontname,Fontsize,Formatblock,Fontcolor,Highlight,HR,Insertchars,Showborders",
				);
				$myDE->AddToolbar("Complete", implode(",|,", $rows));

				//Display the DevEdit control. This *MUST* be called between <form> and </form> tags
				$myDE->ShowControl($width,$height,$path);

			} else {
			?>
				<textarea class="Field500" style="height:200" name="wysiwyg_html"><?php echo str_replace("<br>", "\r\n", $Content); ?></textarea>
			<?php
			}

			$editor = ob_get_contents();
			ob_end_clean();

			return $editor;
		}

		/**
		* GetSomeQuestionsAsOptions
		* Get a list of questin and return them as the code for the options.
		* Questions the user doesn't have access to won't be displayed
		*
		* @param array $questions array of question ids to display
		* @return string The html of the options
		*/
		function GetSomeQuestionsAsOptions($questions=array())
		{
			if (empty($questions)) {
				return '';
			}
			// Get a list of all questions and return them as a list
			// of HTML select box <option> tags
			$catsAllowed = array();
			$catsRestrict = '';
			$questionRestrict = "";
			$output = "";
			if (is_array($_SESSION['user']->groups) && !empty($_SESSION['user']->groups)) {
				foreach ($_SESSION['user']->groups as $group) {
					if (is_array($group->applies['category'])) {
						$catsAllowed = array_merge($catsAllowed, $group->applies['category']);
					}
				}
				$catsAllowed = array_unique($catsAllowed);
			}

			if (!empty($catsAllowed)) {
				$catsRestrict = "categoryid IN ('".implode("', '", $catsAllowed)."') ";
				$questionRestrict = "AND ";
			}

			$questionRestrict .= " q.questionid IN ('".implode("', '", $questions)."') ";

			$query = "SELECT DISTINCT q.questionid, title
			FROM ".$GLOBALS['tablePrefix']."questions q LEFT OUTER JOIN ".$GLOBALS['tablePrefix']."categoryassociations a ON a.questionid = q.questionid
			WHERE $catsRestrict
			$questionRestrict
			ORDER BY title ASC";

			$qResult = $GLOBALS['AKB_DB']->Query($query);

			while ($qRow = $GLOBALS['AKB_DB']->Fetch($qResult)) {
				$GLOBALS['OptionValue'] = $qRow["questionid"];
				$GLOBALS['OptionText'] = htmlspecialchars($qRow["title"], ENT_QUOTES, $GLOBALS['charset']);
				$GLOBALS['OptionSelected'] = '';
				$output .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('Option');
			}

			return $output;
		}
		
		/**
		* ShowNewQuestion
		* Show the page for creating a new question
		*
		* @return void
		*/
		function ShowNewQuestion()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			// Create a new question
			// First up, get form variables if there's an error
			
			$title = "";
			$cat = -1;
			$answer = "";
			$sort = 0;
			$visible = true;
			$GLOBALS['DisplayKeepEditing'] = 'block';
			$GLOBALS['HidePanels'][] = 'QuestionEmailSubmitter';
			$GLOBALS['HidePanels'][] = 'QuestionLastUpdated';
			$GLOBALS['HidePanels'][] = 'QuestionBecomeAuthor';
			$GLOBALS['cancelTodo'] = 'viewQuestions';
			
			// Nothing to show in misc panel on new questions
			$GLOBALS['HidePanels'][] = 'QuestionMiscellaneous';
			$GLOBALS['HidePanels'][] = 'QuestionStatus';

			$GLOBALS['sanDisabled'] = "disabled=\"disabled\"";
			$GLOBALS['AKB_CLASS_HELPER']->populateArticleDates();

			$applies = array();

//			if (is_array($_SESSION['user']->groups)
//			&& !empty($_SESSION['user']->groups)) {
//				foreach ($_SESSION['user']->groups as $group) {
//					if (isset($group->applies['category'])
//					&& is_array($group->applies['category'])) {
//						$applies = array_merge($applies, $group->applies['category']);
//					}
//				}
//			}
			$GLOBALS['Title'] = GetLang('AddQuestionTitle');
			$GLOBALS['Intro'] = GetLang('AddQuestionIntro');
			$GLOBALS['FormAction'] = 'saveNewQuestion';
			$GLOBALS['QuestionTitle'] = $title;
			$GLOBALS['CategoryOptions'] = $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions($cat);
			$GLOBALS['RelatedCategoryOptions'] = $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions(array(0), '<option %s value="%d">%s</option>', 'selected', '- ', false, $applies);
			
			$GLOBALS['RelatedQuestions'] = $this->GetSomeQuestionsAsOptions();
			$GLOBALS['WYSIWYG'] = $this->GetWYSIWYGEditor($answer);
			$GLOBALS['SortOrder'] = $sort;
			$GLOBALS['QuestionKeywords'] = '';
			$GLOBALS['QuestId'] = '';
			$GLOBALS['SubmittedQuestId'] = '';
			$GLOBALS['MetaKeywords'] = '';
			$GLOBALS['MetaDescription'] = '';
			$GLOBALS['ExistingAttachments'] = '';
			$GLOBALS['DisableVisible'] = '';
			$GLOBALS['DetectRelated'] = '';
			$GLOBALS['LastUpdated'] = '';

			// Are we starting from a user submitted question?
			if (isset($_GET["submittedQuestId"])) {
				$sQuestId = $_GET["submittedQuestId"];
				$query = sprintf("select * from %ssubmittedquestions where subquestid='%d'", $GLOBALS["tablePrefix"], $sQuestId);
				$result = $GLOBALS['AKB_DB']->Query($query);

				if ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					$GLOBALS["QuestionTitle"] = htmlspecialchars($row["subject"], ENT_QUOTES, $GLOBALS['charset']);
					$GLOBALS["WYSIWYG"] = $this->GetWYSIWYGEditor(htmlspecialchars($row["message"], ENT_QUOTES, $GLOBALS['charset']));
					$GLOBALS["SubmittedQuestId"] = $sQuestId;
					$GLOBALS['lastupdated'] = $row['posted'];
					foreach (array_keys($GLOBALS['HidePanels'], 'QuestionEmailSubmitter') as $key) {
						unset($GLOBALS['HidePanels'][$key]);
					}
				}
			}

			//Setup groups
			$GLOBALS['groups'] = $this->getGroupsForSelect();
			$GLOBALS['groupListSize'] = 5;

			$GLOBALS['lblRestrictPublic'] = GetLang("RestrictPublicQuest");
			$GLOBALS['lblRestrictPrivate'] = GetLang("RestrictPrivateQuest");

			//New question. No groups associated.
			$GLOBALS['HasGroups'] = 0;

			$GLOBALS["CheckVisible"] = ($visible) ? 'CHECKED' : '';

			if (!$_SESSION['user']->verify('question', 'approve')) {
				$GLOBALS["CheckVisible"] = "";
				$GLOBALS["DisableVisible"] = "DISABLED";
			}
			
			$GLOBALS['CustomFields'] = $this->processCustomFields();
			
			$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("question.form");
			$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
		}
		
		/**
		* processCustomFields
		* Shows the custom fields picker for this question.
		*
		* @return string
		*/		
		function processCustomFields($questionid=0) {
			
			//Get all the custom fields
			$customfields_all = custom_fields_helper::get_all_custom_fields();
			
			if ($customfields_all) {
				$GLOBALS['CFDisplay'] = "table";
			} else {
				$GLOBALS['CFDisplay'] = "none";
			}
			
			//If this is for an existing question, get the ones that are associated.
			$customfields_question = array();
			if ($questionid > 0) {
				$customfields_question = custom_fields_helper::get_custom_fields_by_question($questionid);
			}
			
			$outputHTML = "";
			foreach ($customfields_all as $customfieldid=>$cfObj) {
				$questionAssoc = false;
				if (isset($customfields_question[$customfieldid])) {
					$questionAssoc = true;
				}
				
				//Main Checkbox
				$GLOBALS['ID'] = $cfObj->customfieldid;
				$GLOBALS['Label'] = $cfObj->name;
				$GLOBALS['Name'] = "customfield[".$cfObj->customfieldid."]";
				$GLOBALS['extraAttribute'] = "onclick=\"expandCF(this,'cf_".$cfObj->customfieldid."');\" ";
				
				$GLOBALS['checked'] = "";
				if ($questionAssoc) {
					$GLOBALS['checked'] = "checked=\"checked\" ";
				}
				
				//$outputHTML .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('CheckBox');
				$outputHTML .= "<tr><td valign=\"top\" width=\"190\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".$cfObj->name.":</td>";
				
				//Hidden div
				$GLOBALS['cfid'] = "cf_".$cfObj->customfieldid;
				
				$GLOBALS['cfhidden'] = "none";
				if ($questionAssoc) {
					$GLOBALS['cfhidden'] = "display";
				}
				
				//Culminate cf data.
				$cfdata = "";
				if ($cfObj->type == CF_TYPE__MULTI_CHECK) {
					//Multiple checkbox UI gather.
					$GLOBALS['extraAttribute'] = "";
					$cfmultiStr = "";
					foreach ($cfObj->customFieldDataArray as $cfDataObj) {
						
						$GLOBALS['ID'] = $cfDataObj->customfield_dataid;
						$GLOBALS['Label'] = $cfDataObj->data;
						$GLOBALS['Name'] = "cfdata[".$customfieldid."][".$cfDataObj->customfield_dataid."][]";
						
						//Need to see if this data object is meant to be chosen by looping through the array
						//from the question link table
						$found = false;
						
						if ((isset($customfields_question[$customfieldid])) && (count($customfields_question[$customfieldid]->customFieldDataArray) > 0)) {
							foreach ($customfields_question[$customfieldid]->customFieldDataArray as $searchObj) {
								if ($searchObj->data == $cfDataObj->data) {
									$found = true;
									break;
								}
							}
						}
						
						if ($found) {
							$GLOBALS['checked'] = "checked=\"checked\" ";
						} else {
							$GLOBALS['checked'] = "";
						}
						
						$cfmultiStr .= "<tr><td valign=\"top\">".$GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('CheckBox')."</td></tr>";
					}
					
					$GLOBALS['cfdatamulti'] = $cfmultiStr;
					
					$cfdata = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('cfdata_multicheck');
				} else {
					//Freeform textarea data gather.
					$GLOBALS['cfidkey'] = $customfieldid;
					$GLOBALS['cfdataid'] = $cfObj->customFieldDataArray[0]->customfield_dataid;
					if (isset($customfields_question[$customfieldid])) {
						$GLOBALS['cfdata_value'] = $customfields_question[$customfieldid]->customFieldDataArray[0]->data;
					} else {
						$GLOBALS['cfdata_value'] = "";
					}

					$cfdata = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('cfdata_freeform');
				}
				
				$GLOBALS['cfdata'] = "<td valign=\"top\">".$cfdata."</td></tr>";
				
				$outputHTML .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('CFHiddenOption');
			}
			
			return $outputHTML;
		}
		
		function saveCustomFields($questionid) {
			
			if (!isset($_POST['cfdata'])) {
				return false;
			}
			
			$cfArray = $_POST['cfdata'];
						
			//Now delete questionlinks
			$cfObj = new API_CUSTOMFIELD();
			$cfObj->deleteQuestionLinksByQuestion($questionid);			
			
			if ($cfArray) {
				foreach ($cfArray as $customfieldid=>$tempArr) {

					//Get the populated object
					$cfObj = new API_CUSTOMFIELD($customfieldid,true);

					//Now, if applicable put the question links back in
					foreach ($tempArr as $cfdataid=>$val) {

						//If cfdataid is 0 then its a freeform text
						if ($cfdataid == 0) {
							if ($val != "") {
								$cfObj->addQuestionLink($questionid,$val);
							}
						} else {
							$cfDataObj = new API_CUSTOMFIELDS_DATA();
							$cfDataObj->load($cfdataid);

							$cfObj->addQuestionLink($questionid,$cfDataObj->data);
						}
					}
				}
			}
		}

		/**
		* ShowQuestionList
		* Display the list for managing questions
		*
		* @param string $MsgDesc The message text
		* @param int $MsgStatus The type of message
		*
		* @return void
		*/
		function ShowQuestionList($MsgDesc = "", $MsgStatus = "")
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')
			&& !$_SESSION['user']->verify('question', 'approve')) {
				$this->NoPermission();
				return;
			}
			
			$GLOBALS['BreadcrumEntries'] = array(GetLang("Home") => "index.php", GetLang("ManageQuestions") => "");

			$start = 0;
			$numQuestions = 0;
			$numPages = 0;
			$catsRestrict = '';
			$catsAllowed = array();
			$comments = array();
			$GLOBALS['HideHeading'] = '';
			$GLOBALS['QuestionBulkOptions'] = '';
			if (!isset($GLOBALS['Message'])) {
				$GLOBALS['Message'] = '';
			}
			
			if ($_SESSION['user']->verify('question', 'delete')) {
				$GLOBALS['QuestionBulkOptions'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('QuestionBulkDeleteOptions');
			}

			if ($_SESSION['user']->verify('question', 'edit')) {
				$GLOBALS['ShowCreateButton'] = 'inline';
				$GLOBALS['QuestionBulkOptions'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('QuestionBulkEditOptions');
			} else {
				$GLOBALS['ShowCreateButton'] = 'none';
			}

			if ($_SESSION['user']->verify('question', 'review')) {
				$GLOBALS['ShowReviewButton'] = 'inline';
			} else {
				$GLOBALS['ShowReviewButton'] = 'none';
			}

			$this->InitAdvancedSearch();

			$applies = array();
			if (is_array($_SESSION['user']->groups) && !empty($_SESSION['user']->groups)) {
				foreach ($_SESSION['user']->groups as $group) {
					if (isset($group->applies['category']) && is_array($group->applies['category'])) {
						$applies = array_merge($applies, $group->applies['category']);
					}
				}
			}

			$GLOBALS['CategoryOptions'] = $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions($_SESSION['search']['categories'], "<option %s value='%d'>%s</option>", "selected", $Divider = "- ", $IncludeEmpty = true, $applies);

			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=viewQuestions';
			$GLOBALS['ImagePath'] = '../templates/' . $GLOBALS['template'] . '/Images';
			$GLOBALS['QuestionGrid'] = '';
			$GLOBALS['Nav'] = '';
			$GLOBALS['SearchQuery']	= $_SESSION['search']['q'];

			// {{{ Build the alpha list (A-Z box list)
			$GLOBALS["AlphaList"] = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListHeader');
			$GLOBALS["Item"] = 'articles';
			$letters = GetAlphaList();
			foreach ($letters as $letter) {
				$GLOBALS['Letter'] = $letter;
				$GLOBALS['TermClickLetter'] = sprintf(GetLang("TermClickLetter"), strtolower(GetLang('Questions')), $letter);
				if ($letter == $_SESSION['search']['letter']) {
					$GLOBALS["AlphaList"] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListRow');
				} else {
					$GLOBALS["AlphaList"] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListRow');
				}
			}
			$GLOBALS["AlphaList"] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListFooter');
			// }}

			$this->BuildListQueries();

			if ($MsgDesc != '') {
				$GLOBALS["Message"] = MessageBox($MsgDesc, $MsgStatus);
			}

			$result = $GLOBALS['AKB_DB']->Query($this->countQuery);
			$this->numRecords = $GLOBALS['AKB_DB']->FetchOne($result);

			if ($this->numRecords > 0) {
				$GLOBALS['ManageQuestMessage'] = GetLang('ManageQuestMessage');

				$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.manage');
				$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
			} else {
				$valid_letters = GetAlphaList();
				if (isset($_SESSION['search']['letter']) && in_array($_SESSION['search']['letter'], $valid_letters)) {
					// No questions found when searching by letter
					$GLOBALS['Title'] = GetLang('ManageQuestions');
					$GLOBALS['ManageQuestMessage'] = GetLang('ManageQuestMessage');
					$GLOBALS['ButtonText'] = GetLang('CreateQuestion');
					$GLOBALS['ButtonClass'] = 'Field150';
					$GLOBALS['Message'] .= MessageBox(sprintf(GetLang('NoQuestionLetter'), $_SESSION['search']['letter']), MSG_WARNING);
					$GLOBALS['URL'] = 'index.php?ToDo=createQuestion';
					$GLOBALS['HideHeading'] = 'style="display:none"';
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.manage');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				} elseif (isset($_SESSION['search']['searching'])) {
					// No questions found when searching
					$GLOBALS['Title'] = GetLang('ManageQuestions');
					$GLOBALS['ManageQuestMessage'] = GetLang('ManageQuestMessage');
					$GLOBALS['ButtonText'] = GetLang('CreateQuestion');
					$GLOBALS['ButtonClass'] = 'Field150';
					$GLOBALS['Message'] .= MessageBox(GetLang('NoQuestionSearch'), MSG_WARNING);
					$GLOBALS['URL'] = 'index.php?ToDo=createQuestion';
					$GLOBALS['HideHeading'] = 'style="display:none"';
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.manage');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				} else {
					// No questions exist at all
					$GLOBALS['Style'] = '';
					$GLOBALS['Title'] = GetLang('ManageQuestions');
					$GLOBALS['ButtonText'] = GetLang('CreateQuestion');
					$GLOBALS['ButtonClass'] = 'Field150';
					$GLOBALS['Message'] .= '<br />'.MessageBox(GetLang('NoQuestions'), MSG_SUCCESS).'<br />';
					$GLOBALS['URL'] = 'index.php?ToDo=createQuestion';

					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('messagewithbutton');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				}
			}
		}

		function ShowQuestionsListRemote() {
			//Set pagination variables.
			$page = isset($_GET['page'])? (int) $_GET['page'] : 1;

			$sortVars = array("qid","title","firstname","views","comments","lastupdated","visible","workflowstatus");
			$sortArray = $this->SetupSortingParams($sortVars,"ShowQuestionsListRemote",$page);

			//Get the queries
			$this->BuildListQueries();

			//Setup pagination
			$field = "lastupdated";
			if (isset($_GET['field'])) {
				$_GET['field'];
			}

			$direction = "d";
			if (isset($_GET['direction'])) {
				$direction = $_GET['direction'];
			}

			$result = $GLOBALS['AKB_DB']->Query($this->query);
		
			$this->SetupPaginationLink("ShowQuestionsListRemote",$direction,$field);
			$this->SetupPagination($this->countQuery,$page,AKB_QUESTION_PER_PAGE);

			if ($this->numRecords == 0) {
				die();
			}
			
			$adminTable = new QuestionManage_Table();
			$adminTable->rsData = $result;
			$adminTable->sortArray = $sortArray;

			echo $adminTable->ReturnTable();
			die();
		}

		/**
		* ShowQuestionList
		* Display the list for managing questions
		*
		* @param string $MsgDesc The message text
		* @param int $MsgStatus The type of message
		*
		* @return void
		*/
		function ShowWorkflowQuestionList($MsgDesc = "", $MsgStatus = "")
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')
			&& !$_SESSION['user']->verify('question', 'approve')) {
				$this->NoPermission();
				return;
			}
					
			$GLOBALS['BreadcrumEntries'] = array(GetLang("Home") => "index.php", GetLang("ManageWorkflowArticles") => "");

			$start = 0;
			$numQuestions = 0;
			$numPages = 0;
			$catsRestrict = '';
			$catsAllowed = array();
			$comments = array();
			$GLOBALS['HideHeading'] = '';
			$GLOBALS['QuestionBulkOptions'] = '';
			if (!isset($GLOBALS['Message'])) {
				$GLOBALS['Message'] = '';
			}

			// Used for the option list for bulk update
			if ($_SESSION['user']->verify('question', 'delete')) {
				$GLOBALS['QuestionBulkOptions'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('QuestionBulkDeleteOptions');
			}

			if ($_SESSION['user']->verify('question', 'edit')) {
				$GLOBALS['QuestionBulkOptions'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('QuestionBulkEditOptions');
				$GLOBALS['QuestionBulkOptions'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('QuestionBulkApprovalOptions');
			} else {
			}

			if ($_SESSION['user']->verify('question', 'review')) {
				$GLOBALS['ShowReviewButton'] = 'inline';
			} else {
				$GLOBALS['ShowReviewButton'] = 'none';
			}

			$this->InitAdvancedSearch();

			$GLOBALS['CategoryOptions'] = $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions($_SESSION['search']['categories'], "<option %s value='%d'>%s</option>", "selected", $Divider = "- ", $IncludeEmpty = true, true);

			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=viewWorkflowQuestions';
			$GLOBALS['ImagePath'] = '../templates/' . $GLOBALS['template'] . '/Images';
			$GLOBALS['QuestionGrid'] = '';
			$GLOBALS['Nav'] = '';
			$GLOBALS['SearchQuery']	= $_SESSION['search']['q'];

			// {{{ Build the alpha list (A-Z box list)
			$GLOBALS["AlphaList"] = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListHeader');
			$GLOBALS["LetterPrefix"] = 'wf';
			$GLOBALS["Item"] = 'articles';
			$letters = GetAlphaList();
			foreach ($letters as $letter) {
				$GLOBALS['Letter'] = $letter;
				$GLOBALS['TermClickLetter'] = sprintf(GetLang("TermClickLetter"), strtolower(GetLang('Questions')), $letter);
				if ($letter == $_SESSION['search']['wfletter']) {
					$GLOBALS["AlphaList"] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListRow');
				} else {
					$GLOBALS["AlphaList"] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListRow');
				}
			}
			$GLOBALS["AlphaList"] .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('AlphaListFooter');
			// }}

			$this->BuildListQueries(true);

			if ($MsgDesc != '') {
				$GLOBALS["Message"] = MessageBox($MsgDesc, $MsgStatus);
			}

			$result = $GLOBALS['AKB_DB']->Query($this->countQuery);
			$this->numRecords = $GLOBALS['AKB_DB']->FetchOne($result);
			if ($this->numRecords > 0) {
				$GLOBALS['ManageQuestMessage'] = GetLang('ManagePendingQuestMessage');

				$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('workflowquestion.manage');
				$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
			} else {
				$valid_letters = GetAlphaList();
				if (isset($_SESSION['search']['wfletter']) && in_array($_SESSION['search']['wfletter'], $valid_letters)) {
					// No questions found when searching by letter
					$GLOBALS['Title'] = GetLang('ManageQuestions');
					$GLOBALS['ManageQuestMessage'] = GetLang('ManageQuestMessage');
					$GLOBALS['ButtonText'] = GetLang('CreateQuestion');
					$GLOBALS['ButtonClass'] = 'Field150';
					$GLOBALS['Message'] .= MessageBox(sprintf(GetLang('NoQuestionLetter'), $_SESSION['search']['wfletter']), MSG_WARNING);
					$GLOBALS['URL'] = 'index.php?ToDo=createQuestion';
					$GLOBALS['HideHeading'] = 'style="display:none"';
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('workflowquestion.manage');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				} elseif (isset($_SESSION['search']['searching'])) {
					// No questions found when searching
					$GLOBALS['Title'] = GetLang('ManageQuestions');
					$GLOBALS['ManageQuestMessage'] = GetLang('ManageQuestMessage');
					$GLOBALS['Message'] .= MessageBox(GetLang('NoQuestionSearch'), MSG_WARNING);
					$GLOBALS['HideHeading'] = 'style="display:none"';
					// No questions exist at all
					$GLOBALS['Style'] = '';
					$GLOBALS['Title'] = GetLang('ManageWorkflowArticles');
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('workflowquestion.manage');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				} else {
					// No questions exist at all
					$GLOBALS['Style'] = '';
					$GLOBALS['Title'] = GetLang('ManageWorkflowArticles');
					$GLOBALS['Message'] .= '<br />'.MessageBox(GetLang('NoPendingQuestions'), MSG_SUCCESS).'<br />';
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('message');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				}
			}
		}

		function ShowWorkflowQuestionsListRemote() {
			//Set pagination variables.
			$page = isset($_GET['page'])? (int) $_GET['page'] : 1;

			$sortVars = array("qid","title","firstname","comments","lastupdated","visible","workflowstatus");
			$sortArray = $this->SetupSortingParams($sortVars,"ShowWorkflowQuestionsListRemote",$page);

			//Get the queries
			$this->BuildListQueries(true);

			//Setup pagination
			$field = "lastupdated";
			if (isset($_GET['field'])) {
				$_GET['field'];
			}

			$direction = "d";
			if (isset($_GET['direction'])) {
				$direction = $_GET['direction'];
			}

			$result = $GLOBALS['AKB_DB']->Query($this->query);
		
			$this->SetupPaginationLink("ShowWorkflowQuestionsListRemote",$direction,$field);
			$this->SetupPagination($this->countQuery,$page,AKB_QUESTION_PER_PAGE);

			if ($this->numRecords == 0) {
				die();
			}
			
			$adminTable = new QuestionWorkflowManage_Table();
			$adminTable->rsData = $result;
			$adminTable->sortArray = $sortArray;

			echo $adminTable->ReturnTable();
			die();
		}
		
		/**
		* PreviewFullQuestion
		* Display a preview of a question
		*
		* @return void
		*/
		function PreviewFullQuestion()
		{
			if (isset($_GET['questId'])) {
				$questId = $_GET['questId'];
				$query = sprintf("SELECT title, answer FROM %squestions WHERE questionid='%d'", $GLOBALS['tablePrefix'], $questId);
				$qResult = $GLOBALS['AKB_DB']->Query($query);

				if ($qRow = $GLOBALS['AKB_DB']->Fetch($qResult)) {
					$GLOBALS['Question'] = $qRow['title'];
					$GLOBALS['Answer'] = $qRow['answer'];
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.preview');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				} else {
					echo '<script type="text/javascript" language="javascript">window.close()</script>';
				}
			} else {
				echo '<script type="text/javascript" language="javascript">window.close()</script>';
			}
		}

		/**
		* viewQuestionChanges
		* Display a preview of a question and its latest changes history
		*
		* @return void
		*/
		function viewQuestionChanges()
		{
			$viewChangesConfirmed = false;
			$GLOBALS['DisplayRight'] = 'display:none;';
			$GLOBALS['Screen'] = 'QuestionPreviewContainerFullScreen';
			if (isset($_GET['questId'])) {
				$questId = $_GET['questId'];
				$query = sprintf("SELECT title, answer FROM %squestions WHERE questionid='%d'", $GLOBALS['tablePrefix'], $questId);
				$qResult = $GLOBALS['AKB_DB']->Query($query);

				if ($qRow = $GLOBALS['AKB_DB']->Fetch($qResult)) {
					$GLOBALS['Question'] = $qRow['title'];
					$GLOBALS['Answer'] = $qRow['answer'];
				} else {
					$GLOBALS['Message'] = MessageBox(GetLang('ArticlePreviewFailed'), MSG_ERROR);
					echo "<script>alert('".GetLang('ArticlePreviewFailed')."'); tb_remove();</script>";
					die();
				}
				
				// Check if we need to view the article history.
				if (isset($_GET['viewChanges']) && $_GET['viewChanges'] == '1') {
					// get the latest version from history where its title/body has been changed.
					$query = sprintf("SELECT title, answer FROM %squestions_history WHERE questionid='%d' AND (title != '%s' OR answer NOT LIKE '%s') ORDER BY versionid DESC ", $GLOBALS['tablePrefix'], $questId, $GLOBALS['AKB_DB']->Quote($GLOBALS['Question']), $GLOBALS['AKB_DB']->Quote($GLOBALS['Answer']));
					$query .= $GLOBALS['AKB_DB']->AddLimit(0, 1);

					$qhResult = $GLOBALS['AKB_DB']->Query($query);
	
					if ($qRow = $GLOBALS['AKB_DB']->Fetch($qhResult)) {
						$GLOBALS['QuestionHistory'] = $qRow['title'];
						$GLOBALS['AnswerHistory'] = $qRow['answer'];
						$viewChangesConfirmed = true;
					} else {
							$GLOBALS['QuestionHistory'] = $GLOBALS['Question'];
							$GLOBALS['AnswerHistory'] = $GLOBALS['Answer'];
							$viewChangesConfirmed = true;
					}
				}
				
				if ($viewChangesConfirmed) {
					$GLOBALS['DisplayRight'] = '';
					$GLOBALS['Screen'] = 'QuestionPreviewContainerHalfScreen';
				}
				
				$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.viewchanges');
				$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
			} else {
				$GLOBALS['Message'] = MessageBox(GetLang('ArticlePreviewFailed'), MSG_ERROR);
				echo "<script>alert('".GetLang('ArticlePreviewFailed')."'); tb_remove();</script>";
				die();
			}
		}

		function ReturnCommentCell($questionid, $comments)
		{
			if($comments == 0) return $comments;

			if($_SESSION['user']->verify('comment', 'edit'))
			{
				return "<a href=\"index.php?ToDo=viewComments&amp;questionid={$questionid}\">{$comments}</a>";
			}
			else
				return $comments;
		}

		function ReturnRatingCell($posvotes,$negvotes) {
			$GLOBALS['ImagePath'] = 'images';

			$GLOBALS['Votes'] = $posvotes + $negvotes;
			$GLOBALS['VotesString'] = ($GLOBALS['Votes'] == 1) ?
				GetLang('QuestVote')
				: GetLang('QuestVotes');

			if ($GLOBALS['Votes'] > 0) {
				$posPer = floor(($posvotes / $GLOBALS['Votes']) * 100);
				$negPer = floor(($negvotes / $GLOBALS['Votes']) * 100);

				$GLOBALS['LowRate'] = $posPer;
				$GLOBALS['HighRate'] = $negPer;

				$output = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('Rated');
			} else {
				$output = GetLang('QuestNoVotes');
			}

			return $output;

			//$GLOBALS['Votes'] = number_format($GLOBALS['Votes']);
		}

		/**
		* UpdateVisible
		* Update the visiblitiy of a question
		*
		* @return void
		*/
		function UpdateVisible()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'approve')) {
				$this->NoPermission();
				return;
			}

			if (isset($_GET['questId']) && isset($_GET['visible'])) {
				$question = new API_QUESTION();
				$question->load($_GET['questId']);
				$_POST['visible'] = $_GET['visible'];

				if ($question->save()) {
					if ($_GET['visible'] == 1) {
						$GLOBALS['Message'] = MessageBox(GetLang('QuestionVisibleSuccessfully'), MSG_SUCCESS);
					} else {
						$GLOBALS['Message'] = MessageBox(GetLang('QuestionHiddenSuccessfully'), MSG_SUCCESS);
					}
				}
			}
		}

		/**
		* SaveUpdatedQuestion
		* Update a question in the database
		*
		* @return void
		*/
		function SaveUpdatedQuestion($createAsNew=false)
		{
			if ($createAsNew) {
				return $_POST['questionid'] = $this->SaveNewQuestion(false);
			}

			if (isset($_POST)) {
				$_SESSION['post_backup'] = $_POST;
			}

			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			// Check if a category is selected
			if (!isset($_POST['category']) || (sizeof($_POST['category']) == 1 and $_POST['category'][0] == '0')) {
				return ;
			}
			
			if (!isset($_POST) && isset($_SESSION['post_backup'])) {
				$_POST = $_SESSION['post_backup'];
			}

			// check expiry
			if (isset($_POST["expires"]) && $_POST["expires"] == "on") {
				$_POST["enableexpiry"] = 1;
			} else {
				$_POST["enableexpiry"] = 0;
			}
			
			// start date
			$_POST["startdate"] = sprintf("%s-%s-%s %s", $_POST["startyear"],
				$_POST["startmonth"], $_POST["startday"], date('H:i:s',strtotime($_POST['starttime'])));

			// expiry date
			if ($_POST["enableexpiry"] == 1) {
				$_POST["expirydate"] = sprintf("%s-%s-%s %s", $_POST["endyear"],
					$_POST["endmonth"], $_POST["endday"], date('H:i:s',strtotime($_POST['endtime'])));
			} else {
				$_POST["expirydate"] = $_POST["startdate"];
			}

			if (isset($_POST['visible'])  && strtolower($_POST['visible']) == 'on' && $_SESSION['user']->verify('question', 'approve')) {
				$_POST['visible'] = 1;
			} else {
				$_POST['visible'] = 0;
			}
			if (isset($_POST['featured']) && $_POST['featured'] == '1') {
				$_POST['featured'] = 1;
			} else {
				$_POST['featured'] = 0;
			}
			$_POST['detectrelated'] = isset($_POST['detectrelated']) ? 1 : 0;
			$_POST['answer'] = $_POST['wysiwyg_html'];

			if (isset($_POST['questionsrelated'])) {
				$_POST['related'] = implode(",", $_POST['questionsrelated']);
			} else {
				$_POST['related'] = '';
			}
			$problem = true;

			$q = new API_QUESTION();
			$q->load($_POST['questionid']);
			
			// check for redirect page go to pending article or not
			if ($q->workflowstatus == WF_STATUS_DISAPPROVED || $q->workflowstatus == WF_STATUS_REPENDING || $q->workflowstatus == WF_STATUS_PENDING) {
				$redirectToPending = true;
			} else {
				$redirectToPending = false;
			}

			// Workflow process... Part 1
			// get the existing category associations
			$existingCategories = $q->get_category_associations($_POST['questionid']);
			
			$tmpWorkflowStatus = '';
			$in_grp_ids = '';
			$in_grp_edit_ids = '';
			$approval_users = array();
			$users_added = array();
			$num_approval_users = 0;
			$totalCategories = array();
			$validGroupEdit = array();
			$totalCategoriesNames = '';
			$continue = true;
			$totalCategoriesNames = '';
			
			$intersectCategories = array();
			$unionCategories = array();
			$emailToCategories = array();
			if (isset($_POST['category']) && is_array($_POST['category']) && sizeof($_POST['category']) && validUrl()) {
				$intersectCategories = array_intersect($existingCategories, $_POST['category']);
				$categoryQueryString = "'" . implode("','", $_POST['category']) . "'";
				$query = sprintf("select categoryid, name, approvaltype from %scategories where categoryid in (%s)", $GLOBALS['tablePrefix'], $categoryQueryString);
				$result = $GLOBALS['AKB_DB']->Query($query);
				while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					$row['edit'] = false;
					if ($row['approvaltype'] == CATEGORIES_ALWAYS_APPROVAL && in_array($row['categoryid'], $intersectCategories)) {
						$row['edit'] = true;
					}
					if ($row['approvaltype'] == CATEGORIES_ALWAYS_APPROVAL || ($row['approvaltype'] == CATEGORIES_ONCE_APPROVAL && !in_array($row['categoryid'], $intersectCategories)) ) {
						$emailToCategories['ids'][] = $row['categoryid'];
						$emailToCategories['names'][] = $row['name'];
						if ($row['edit']) {
							$emailToCategories['edit'][] = $row['categoryid'];
						}
					}
				}
			}
			
			if(isset($emailToCategories['ids']) && $_SESSION['user']->userid != 1) {
				// Get all the available groups
				$query = sprintf('SELECT groupid, name FROM %sgroups ORDER BY name ASC', $GLOBALS['tablePrefix']);
				$result = $GLOBALS['AKB_DB']->Query($query);
				$validGroups = array();
				while($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					$group = new API_GROUP();
					$groupid = $row['groupid'];
					$group->load($groupid);
					
					$groupPerm = $group->perms;
					if (isset($groupPerm['question']['edit']) && $groupPerm['question']['edit'] == '1'
					&& isset($groupPerm['category']['approve']) && $groupPerm['category']['approve'] == '1'
					) {
						if (((is_array($group->applies['category']) && 
						(array_intersect($emailToCategories['ids'], $group->applies['category']))) || $group->applies['category'] == 'all') 
						&& $group->applies['feonly'] != '1') {
							if (is_array($group->applies['category'])) {
								$intersectGroupCat = array_intersect($emailToCategories['ids'], $group->applies['category']);
							} else {
								$intersectGroupCat = $emailToCategories['ids'];
							}
							$validGroups[] = $groupid;
							if (isset($emailToCategories['edit']) && array_intersect($intersectGroupCat, $emailToCategories['edit'])) {
								$validGroupEdit[] = $groupid;
							}
						}
					}
				}
				
				$in_grp_ids = "'" . implode("','", $validGroups) . "'";
				$validUserEdit = array();
				if (sizeof($validGroupEdit)) {
					$in_grp_edit_ids = "'" . implode("','", $validGroupEdit) . "'";
					$query = sprintf("SELECT DISTINCT u.userid
										FROM %smembers m, %susers u
										WHERE m.userid = u.userid
										AND m.groupid IN (%s)
					", $GLOBALS['tablePrefix'], $GLOBALS['tablePrefix'], $in_grp_edit_ids);
					
					$result = $GLOBALS['AKB_DB']->Query($query);
					while($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$validUserEdit[] = $row['userid'];
					}
				}

				
				$query = sprintf("SELECT DISTINCT u.userid, u.firstname, u.lastname, u.username, u.email
									FROM %smembers m, %susers u
									WHERE m.userid = u.userid
									AND m.groupid IN (%s)
				", $GLOBALS['tablePrefix'], $GLOBALS['tablePrefix'], $in_grp_ids);
				
				$totalCategoriesNames = "\n\n* " . implode("\n* ", $emailToCategories['names']);
				if (sizeof($emailToCategories['names']) == 1) {
					$totalCategoriesNames = "\n\n* " . array_pop($emailToCategories['names']);
				}
				
				$result = $GLOBALS['AKB_DB']->Query($query);
				$num_approval_users = $GLOBALS['AKB_DB']->CountResult($query);

				if($num_approval_users > 0) {
					// This article requires approval before publishing
					$tmpWorkflowStatus = WF_STATUS_REPENDING;

					while($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						if ($row['userid'] == $_SESSION['user']->userid) {
							$continue = false;
							$tmpWorkflowStatus = (isset($_POST['workflowstatus'])) ? $_POST['workflowstatus'] : WF_STATUS_APPROVED;
						}
						if(!in_array($row['email'], $users_added)) {
							$row['edit'] = false;
							if (in_array($row['userid'], $validUserEdit)) {
								$row['edit'] = true;
							}
							array_push($approval_users, $row);
							array_push($users_added, $row['email']);
						}
					}
					if ($tmpWorkflowStatus != '') {
						$_POST['workflowstatus'] = $tmpWorkflowStatus;
					}
				}
			} else {
				$_POST['workflowstatus'] = (isset($_POST['workflowstatus'])) ? $_POST['workflowstatus'] : WF_STATUS_AUTO_APPROVED;
			}

			$_POST['workflowstatus'] = (isset($_POST['workflowstatus']) && ($q->workflowstatus != WF_STATUS_PENDING || $_POST['workflowstatus'] != WF_STATUS_REPENDING)) ? $_POST['workflowstatus'] : $q->workflowstatus;
			if (!validUrl()) {
				$_POST['workflowstatus'] = WF_STATUS_AUTO_APPROVED;
				$redirectToPending = false;
			} else {
				if (isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && $q->get_owner($_POST['questionid']) == $_SESSION['user']->userid && !$this->HasQuestionApprovalEditPerm($_POST['questionid'], WF_STATUS_DISAPPROVED) && $q->workflowstatus == WF_STATUS_DISAPPROVED) {
					$redirectToPending = false;
				}
			}
			
			
			if (isset($_POST['becomeauthor']) && $_POST['becomeauthor'] == 1) {
				$_POST['userid'] = $_SESSION['user']->userid;
			} else {
				$_POST['userid'] = $q->userid;
			}

			$saveresult = $q->save();

			if ($saveresult) {
				$problem = false;
				unset($_SESSION['post_backup']);
			}

			//Delete groups before we do anything.
			$query = sprintf("delete from %squestion_auth where questionid='%d'", $GLOBALS['tablePrefix'], $_POST['questionid']);
			$GLOBALS['AKB_DB']->Query($query);

			if ($_POST['restrict'] == 1) {
				//Now we save the groups if the restrictions are to true.
				if ((isset($_POST['groups'])) && (is_array($_POST['groups']))) {
					for ($i = 0; $i < sizeof($_POST['groups']); $i++) {
						$query = sprintf("insert into %squestion_auth(questionid, groupid) values(%d, %d)", $GLOBALS['tablePrefix'], $_POST['questionid'], $_POST['groups'][$i]);
						$GLOBALS['AKB_DB']->Query($query);
					}
				}
			}

			// Save the category associations
			$query = sprintf("delete from %scategoryassociations where questionid='%d'", $GLOBALS['tablePrefix'], $_POST['questionid']);
			$GLOBALS['AKB_DB']->Query($query);

			for ($i = 0; $i < sizeof($_POST['category']); $i++) {
				$query = sprintf("insert into %scategoryassociations(categoryid, questionid) values(%d, %d)", $GLOBALS['tablePrefix'], $_POST['category'][$i], $_POST['questionid']);
				$GLOBALS['AKB_DB']->Query($query);
			}

			if ($_POST['workflowstatus'] == WF_STATUS_AUTO_APPROVED || $_POST['workflowstatus'] == WF_STATUS_APPROVED) {
				// Save the category associations history
				$query = sprintf("delete from %scatassoc_history where questionid='%d'", $GLOBALS['tablePrefix'], $_POST['questionid']);
				$GLOBALS['AKB_DB']->Query($query);
	
				for ($i = 0; $i < sizeof($_POST['category']); $i++) {
					$query = sprintf("insert into %scatassoc_history(categoryid, questionid) values(%d, %d)", $GLOBALS['tablePrefix'], $_POST['category'][$i], $_POST['questionid']);
					$GLOBALS['AKB_DB']->Query($query);
				}
			}
			
			// Get a list of attachments for this article
			$arrAtt = $this->GetAttachments($_POST['questionid']);

			if (is_array($arrAtt) && !empty($arrAtt)) {
				$arrAtt1 = array();
				// Do we need to delete any of the attachments?
				foreach ($_POST as $k=>$v) {
					if (strpos($k, 'att_') !== false) {
						$arrAtt1[] = base64_decode(substr($k, 4, strlen($k)));
					}
				}

				if (sizeof($arrAtt1) != sizeof($arrAtt)) {
					// One or more attachments need to be deleted!
					foreach ($arrAtt as $f) {
						if (!in_array($f, $arrAtt1)) {
							// Remove the attachment from pageindex table.
							$attRemoveQuery = "DELETE FROM " . $GLOBALS['tablePrefix'] . "pageindex \n";
							$attRemoveQuery .= "WHERE questionid = '{$_POST['questionid']}' \n";
							$attRemoveQuery .= "AND filename = '$f' \n";
							$GLOBALS['AKB_DB']->Query($attRemoveQuery);
							@unlink(sprintf('../attachments/%d/%s', $_POST['questionid'], $f));
						}
					}
				}
			}

			// Work with the attachments
			$this->SaveAttachments((int) $_POST['questionid']);

			$this->SendSubscriberEmails((int) $_POST['questionid']);
			
			$this->saveCustomFields((int)$_POST['questionid']);
			
			// ----- Workflow logic part 2 -----
			// Are there multiple categories that require
			// articles to get approval before publishing?
			if($num_approval_users > 0 && $continue && validUrl()) {
				foreach($approval_users as $approval_user) {
					// Send the approval emails out
					$name = $approval_user['username'];
					if (trim($approval_user['firstname']) != '' || trim($approval_user['lastname']) != '') {
						$name = trim($approval_user['firstname']) . ' ' . trim($approval_user['lastname']);
					}
					
					if ($approval_user['edit']) {
						$message = sprintf(GetLang('ApprovalArticleMessageEdit'), $name,"\n\n", $totalCategoriesNames,"\n\n", $GLOBALS['pathToKB'], $_POST['questionid'], 1);
						$subject = GetLang('ApprovalArticleSubjectEdit');
					} else {
						$message = sprintf(GetLang('ApprovalArticleMessage'), $name,"\n\n", $totalCategoriesNames,"\n\n", $GLOBALS['pathToKB'], $_POST['questionid'], 1);
						$subject = GetLang('ApprovalArticleSubject');
					}
					
					$email = new Email_API();
					setEmailVars($email);
					$email->Set('CharSet', $GLOBALS['charset']);
					$email->From($GLOBALS['contactEmail']);
					$email->Set('Subject', $subject);
					$email->AddBody('text', $message);
					$email->AddRecipient($approval_user['email'], '', 'h');
					$email_result = $email->Send();
				}
				// Change the success message
				$success_msg = sprintf(GetLang('QuestionSavedEditRequiresApproval'), $_POST['title']);
			} else {
				$qcontrol = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('MessageBoxQuestionControl');
				$success_msg = GetLang('QuestionSaved').$qcontrol;
			}
			
			if (isset($_POST['SubmitEditButton1']) || isset($_POST['SubmitEditButton2'])) {
				$GLOBALS['BreadcrumEntries'][GetLang("UserManageQuestions")] = "index.php?ToDo=viewQuestions";
				$GLOBALS['BreadcrumEntries'][GetLang("EditQuestionTitle")] = "";
			}
			
			if ($problem) {
				if (isset($_POST['SubmitEditButton1']) || isset($_POST['SubmitEditButton2'])) {
					$this->EditQuestion((int) $_POST['questionid'], GetLang('QuestionSaved'), MSG_ERROR);
				} else {
					if ($redirectToPending) {
						$this->ShowWorkflowQuestionList(GetLang('QuestionSaved'), MSG_ERROR);
					} else {
						$this->ShowQuestionList(GetLang('QuestionSaved'), MSG_ERROR);
					}
				}
			} else {
				$GLOBALS['UpdatedEditLink'] = 'index.php?ToDo=editQuestion&amp;questionid='.$_POST['questionid'];
				$GLOBALS['UpdatedPreview'] = "javascript:previewQuestion(".$_POST['questionid'].")";
				$GLOBALS['UpdatedFE'] = GetUrl('question', $_POST['questionid']);

				$qcontrol = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('MessageBoxQuestionControl');
				if ($redirectToPending) {
					if (isset($_POST['SubmitEditButton1']) || isset($_POST['SubmitEditButton2'])) {
						$this->EditQuestion((int) $_POST['questionid'], GetLang('QuestionSaved'), MSG_SUCCESS);
					} else {
						$this->ShowWorkflowQuestionList(GetLang('QuestionSaved').$qcontrol, MSG_SUCCESS);
					}
				} else {
					if ($_POST['workflowstatus'] != WF_STATUS_REPENDING) {
						if (isset($_POST['SubmitEditButton1']) || isset($_POST['SubmitEditButton2'])) {
							$this->EditQuestion((int) $_POST['questionid'], GetLang('QuestionSaved'), MSG_SUCCESS);
						} else {
							$this->ShowQuestionList(GetLang('QuestionSaved').$qcontrol, MSG_SUCCESS);
						}
					} else {
						$this->ShowQuestionList(sprintf(GetLang('QuestionSavedRequiresApproval'), $_POST['title']), MSG_SUCCESS);
					}
				}
			}
		}

		/**
		* CopyQuestion
		*
		* Takes the currently setup question and copies.
		*
		* @return void
		*/
		function CopyQuestion() {
			$questionId = (int)$_GET['questionid'];
			$successObj = false;

			if ($questionId > 0) {
				$qObj = new API_QUESTION();
				$qObj->load($questionId);
				if (!$this->HasQuestionApprovalEditPerm($questionId, $qObj->workflowstatus)) {
					$this->NoPermission();
					return false;
				}
				if (!validUrl()) {
					$_POST['workflowstatus'] = WF_STATUS_AUTO_APPROVED;
				} else {
					$_POST['workflowstatus'] = $qObj->workflowstatus;
				}
				//We need to do this to take old questions into consideration
				$save = false;

				if ($qObj->startdate == "0000-00-00 00:00:00") {
					$_POST['startdate'] = date("Y-m-d H:i:s");
					$save = true;
				}

				if ($qObj->expirydate == "0000-00-00 00:00:00") {
					$_POST['expirydate'] = date("Y-m-d H:i:s");
					$save = true;
				}
				
				if ($save) {
					$qObj->save();
				}

				$successObj = $qObj->copy();
				
				// Copy the existing categories across
				$_POST['category_ids'] = $successObj->get_category_associations($questionId);
				if (sizeof($_POST['category_ids'])) {
					$newQuestionId = $successObj->questionid;
					$successObj->set_category_associations($newQuestionId);
				}
				
				// Copy the existing attachments across
				$this->CopyAttachments($questionId, $newQuestionId);
			}

			if ($successObj) {
				$_POST['title'] = "Copy of ".$successObj->title;

				$successObj->save();

				$this->ShowQuestionList(GetLang("CopySuccess"), MSG_SUCCESS);
			} else {
				$this->ShowQuestionList(GetLang("CopyError"), MSG_ERROR);
			}
		}

		/**
		* EditQuestion
		* Display the interface for editing a question
		*
		* @return void
		*/
		function EditQuestion($questionId=0, $MsgDesc='', $MsgStatus='')
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			$cat = array();
			$rel = array();
			$c = 0;
			$applies = array();
			$GLOBALS['DisplayKeepEditing'] = 'block';
			$GLOBALS['SubmittedQuestId'] = '';
			$GLOBALS['DetectRelated'] = '';
			$GLOBALS['DisableVisible'] = '';
			$GLOBALS['ExistingAttachments'] = '';
			$GLOBALS['CheckVisible'] = '';
			$GLOBALS["CheckFeatured"] = '';
			$GLOBALS['HidePanels'][] = 'QuestionEmailSubmitter';
			$GLOBALS['Title'] = GetLang('EditQuestionTitle');
			$GLOBALS['Intro'] = GetLang('EditQuestionIntro');
			$GLOBALS['statusOnchange'] = '';
			if (is_array($_SESSION['user']->groups) && !empty($_SESSION['user']->groups)) {
				foreach ($_SESSION['user']->groups as $group) {
					if (isset($group->applies['category']) && is_array($group->applies['category'])) {
						$applies = array_merge($applies, $group->applies['category']);
					}
				}
			}
			
			if ($questionId > 0) {
				$_GET['questionid'] = $questionId;
			}

			if (isset($_GET['questionid'])) {
				$questId = $_GET['questionid'];
				$query = sprintf("select * from %squestions where questionid='%d'", $GLOBALS["tablePrefix"], $questId);
				$qResult = $GLOBALS['AKB_DB']->Query($query);

				if ($qRow = $GLOBALS['AKB_DB']->Fetch($qResult)) {
					$title =	htmlspecialchars($qRow['title'], ENT_QUOTES, $GLOBALS['charset']);
					$answer =	$qRow['answer'];
					$sort =		$qRow['sortorder'];
					$visible =	$qRow['visible'];
					$featured = $qRow['featured'];
					$GLOBALS['DisplayKeepEditing'] = 'block';
					$workflowstatus = $qRow['workflowstatus'];
					$userid = $qRow['userid'];

					if ($qRow['enableexpiry'] == 1) {
						$GLOBALS['DoesExpire'] = "checked=\"checked\"";
					}
					$sdatetime = explode(" ",$qRow['startdate']);
					$edatetime = explode(" ",$qRow['expirydate']);

					$date = $sdatetime[0];
					$sarrDate = explode("-", $date);
					$date = $edatetime[0];
					$earrDate = explode("-", $date);

					$time = $sdatetime[1];
					$sarrTime = explode(":", $time);
					$time = $edatetime[1];
					$earrTime = explode(":", $time);

					$GLOBALS['AKB_CLASS_HELPER']->populateArticleDates($sarrDate[2],$sarrDate[1],$sarrDate[0],$sarrTime[0],$sarrTime[1],$sarrTime[2],
						$earrDate[2],$earrDate[1],$earrDate[0],$earrTime[0],$earrTime[1],$earrTime[2]);

					if ($qRow['detectrelated'] == 1) {
						$GLOBALS['DetectRelated'] = 'checked';
					}

					// Put all groups into an array (if applicable)
					$groups = array();
					$query = sprintf("select groupid from %squestion_auth where questionid='%d'", $GLOBALS["tablePrefix"], $questId);
					$result = $GLOBALS['AKB_DB']->Query($query);

					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$groups[] = $row['groupid'];
					}

					$GLOBALS['HasGroups'] = (int)$groups;
					
					// Put all categories into an array
					$query = sprintf("select distinct c.categoryid, c.approvaltype from %scategoryassociations ca, %scategories c  where ca.questionid='%d' and ca.categoryid = c.categoryid ", $GLOBALS["tablePrefix"],$GLOBALS["tablePrefix"], $questId);
					$result = $GLOBALS['AKB_DB']->Query($query);

					$catAlwaysReqApp = array();
					$catReqAppOnce = array();
					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$cat[] = $row['categoryid'];
						if ($row['approvaltype'] == CATEGORIES_ALWAYS_APPROVAL) {
							$catAlwaysReqApp[] = $row['categoryid'];
						} elseif ($row['approvaltype'] == CATEGORIES_ONCE_APPROVAL) {
							$catReqAppOnce[] = $row['categoryid'];
						}
					}

					
					if (validUrl()) {
						if (sizeof($catAlwaysReqApp)) {
							if (!$GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($catAlwaysReqApp)) {
								$GLOBALS['DisplayKeepEditing'] = 'none';
								$GLOBALS['Message'] = '<div class="HelpInfo"><img align="left" src="images/info.gif"/>'.GetLang('NoAppPermEditMessage').'</div>';
								if ($workflowstatus == WF_STATUS_PENDING || $workflowstatus == WF_STATUS_REPENDING) {
									$this->NoPermission();
									return false;
								}
								if ($workflowstatus == WF_STATUS_DISAPPROVED && !($userid == $_SESSION['user']->userid && isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && $workflowstatus == WF_STATUS_DISAPPROVED)) {
									$this->NoPermission();
									return false;
								}
							}
						}
						if (sizeof($catReqAppOnce)) {
							if (!$GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($catReqAppOnce)) {
								if ($workflowstatus == WF_STATUS_PENDING || $workflowstatus == WF_STATUS_REPENDING) {
									$this->NoPermission();
									return false;
								}
								if ($workflowstatus == WF_STATUS_DISAPPROVED && !($userid == $_SESSION['user']->userid && isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && $workflowstatus == WF_STATUS_DISAPPROVED)) {
									$this->NoPermission();
									return false;
								}
							}
						}
					}
					$GLOBALS['cancelTodo'] = 'viewQuestions';
					// if this article is pending, check if the user has the permission to edit this article
					if ($workflowstatus == WF_STATUS_PENDING || $workflowstatus == WF_STATUS_REPENDING) {
						if (!$GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($cat)) {
							$this->NoPermission();
							return;
						}
						$GLOBALS['cancelTodo'] = 'viewWorkflowQuestions';
						$GLOBALS['BreadcrumEntries'] = array(GetLang("Home") => "index.php", GetLang("ManageWorkflowArticles") => "index.php?ToDo=viewWorkflowQuestions", GetLang("EditQuestionTitle") => "");
					}
					
					if ($workflowstatus == WF_STATUS_DISAPPROVED && !($userid == $_SESSION['user']->userid && isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && $workflowstatus == WF_STATUS_DISAPPROVED)) {
						if (!$GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($cat)) {
							$this->NoPermission();
							return;
						}
						$GLOBALS['cancelTodo'] = 'viewWorkflowQuestions';
						$GLOBALS['BreadcrumEntries'] = array(GetLang("Home") => "index.php", GetLang("ManageWorkflowArticles") => "index.php?ToDo=viewWorkflowQuestions", GetLang("EditQuestionTitle") => "");
					}

					
					// Put all related questions into an array
					$rel = explode(",", $qRow['related']);

					$GLOBALS['FormAction'] = 'saveUpdatedQuestion';
					$GLOBALS['QuestId'] = $questId;
					$GLOBALS['QuestionTitle'] = $title;
					
					$GLOBALS['CategoryOptions'] = $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions($cat, '<option %s value="%d">%s</option>', 'selected', '- ', true, $applies);
					$GLOBALS['RelatedCategoryOptions'] = $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions(array(0), '<option %s value="%d">%s</option>', 'selected', '- ', true, $applies);
					$GLOBALS['RelatedQuestions'] = $this->GetSomeQuestionsAsOptions($rel);
					$GLOBALS['WYSIWYG'] = $this->GetWYSIWYGEditor($answer);
					$GLOBALS['SortOrder'] = $sort;
					$GLOBALS['MetaKeywords'] = htmlspecialchars($qRow['metakeywords'], ENT_QUOTES, $GLOBALS['charset']);
					$GLOBALS['MetaDescription'] = htmlspecialchars($qRow['metadescription'], ENT_QUOTES, $GLOBALS['charset']);
					$GLOBALS['LastUpdated'] = $qRow['lastupdated'];

					$GLOBALS['WorkFlowStatusOptions'] = decodeWorkflowStatus($workflowstatus);
					if ($GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($cat)) {
						$GLOBALS['statusOnchange'] = 'onChange="if (this.value != \''.WF_STATUS_REPENDING.'\' && this.value != \''.WF_STATUS_PENDING.'\') {ShowApprovalForm(this.value, 1, '.$questId.');}"';
						$GLOBALS['WorkFlowStatusOptions']	= $this->GetStatusOptions($workflowstatus,false,500);
					}
					
					$GLOBALS['groups'] = $this->getGroupsForSelect($groups);
					$GLOBALS['groupListSize'] = 5;

					// Display the existing attachments (if any)
					if ($this->GetNumberOfAttachments($questId) > 0) {
						$GLOBALS["ExistingAttachments"] = sprintf("
						<tr>
							<td class=\"FieldLabel\">
								&nbsp;&nbsp;&nbsp;%s:
							</td>
							<td>
								<table cellspacing=0 cellpadding=0 border=0>
						", GetLang("QuestionExistingAttachments"));

						$arrAtt = $this->GetAttachments($questId);

						foreach ($arrAtt as $f) {
							$data = base64_encode(sprintf('%s|%s', $questId, $f));

							$GLOBALS["ExistingAttachments"] .= "<tr><td>";
							$GLOBALS["ExistingAttachments"] .= sprintf("<input checked=\"checked\" type=\"checkbox\" name=\"att_%s\">%s <a href=\"../getattachment.php?data=".$data."\" target=\"_new\">Open</a></td>", base64_encode($f), $f);

							if ($c++ == 0) {
								$GLOBALS["ExistingAttachments"] .= sprintf("

											<td>
												&nbsp;&nbsp;<img onmouseout=\"HideHelp(this)\" onmouseover=\"ShowHelp(this, '%s', '%s')\" src=\"images/help.gif\" width=\"24\" height=\"16\" border=\"0\">
											</td>
								", GetLang("QuestionExistingAttachments"), GetLang("QuestionExistingAttachmentsHelp"));
							} else {
								$GLOBALS["ExistingAttachments"] .= "<td></td>";
							}
							$GLOBALS["ExistingAttachments"] .= "</tr>";
						}

						$GLOBALS["ExistingAttachments"] .= sprintf("</table></td></tr>");
					}

					if ($visible) {
						$GLOBALS["CheckVisible"] = "checked=\"checked\"";
					}
					
					if ($featured) {
						$GLOBALS["CheckFeatured"] = "checked=\"checked\"";
					}

					$GLOBALS['CustomFields'] = $this->processCustomFields($questId);
					
					$GLOBALS['lblRestrictPublic'] = GetLang("RestrictPublicQuest");
					$GLOBALS['lblRestrictPrivate'] = GetLang("RestrictPrivateQuest");

					if (isset($_GET['toapp']) && $_GET['toapp'] == '1') {
						$GLOBALS["Message"] = MessageBox(GetLang("ApprovalQuestionEdit"), MSG_INFORMATION);
					}
					
					if (!validUrl()) {
						$GLOBALS['HidePanels'][] = 'QuestionStatus';
					}
					
					if ($MsgDesc != '') {
						$GLOBALS["Message"] = MessageBox($MsgDesc, $MsgStatus);
					}
					$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("question.form");
					$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
				} else {
					$this->ShowQuestionList();
				}
			} else {
				$this->ShowQuestionList();
			}
		}
		
		/**
		* HasQuestionApprovalEditPerm
		* Check the user permission to edit the article
		*
		* @param int $QuestId The question id to be checked

		* @return boolean Return if the user has permission right to modify the article/question
		*/
		function HasQuestionApprovalEditPerm($QuestId, $WorkflowStatus)
		{
			if (validUrl()) {
				// Put all categories into an array
				$query = sprintf("select distinct c.categoryid, c.approvaltype from %scategoryassociations ca, %scategories c  where ca.questionid='%d' and ca.categoryid = c.categoryid ", $GLOBALS["tablePrefix"],$GLOBALS["tablePrefix"], $QuestId);
				$result = $GLOBALS['AKB_DB']->Query($query);
	
				$catAlwaysReqApp = array();
				$catReqAppOnce = array();
				while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					if ($row['approvaltype'] == CATEGORIES_ALWAYS_APPROVAL) {
						$catAlwaysReqApp[] = $row['categoryid'];
					} elseif ($row['approvaltype'] == CATEGORIES_ONCE_APPROVAL) {
						$catReqAppOnce[] = $row['categoryid'];
					}
				}
	
				if (sizeof($catAlwaysReqApp)) {
					if (!$GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($catAlwaysReqApp)) {
						if ($WorkflowStatus == WF_STATUS_PENDING || $WorkflowStatus == WF_STATUS_REPENDING || $WorkflowStatus == WF_STATUS_DISAPPROVED) {
							return false;
						}
					}
				}
				if (sizeof($catReqAppOnce)) {
					if (!$GLOBALS['AKB_CLASS_AUTH']->HasApprovalAccess($catReqAppOnce)) {
						if ($WorkflowStatus == WF_STATUS_PENDING || $WorkflowStatus == WF_STATUS_REPENDING || $WorkflowStatus == WF_STATUS_DISAPPROVED) {
							return false;
						}
					}
				}
			}
			return true;
		}
		/**
		* GetAttachments
		* Return an array of attachment filenames for the given question id
		*
		* @param int $QuestId The question id to get the attachments of

		* @return array The array of relative filenames
		*/
		function GetAttachments($QuestId)
		{
			// Workout how many attachments the selected question has
			$arrQuestions = array();
			$dir = sprintf("../attachments/%d", $QuestId);

			if (is_dir($dir)) {
				if ($dh = opendir($dir)) {
					while (($file = readdir($dh)) !== false) {
						if ($file != "." && $file != "..") {
							$arrQuestions[] = $file;
						}
					}
					closedir($dh);
				}
			}
			return $arrQuestions;
		}

		/**
		* GetNumberOfAttachments
		* Return the number of attachments for the question
		*
		* @param int $QuestId The question id to get the attachments of

		* @return int The number of attachments
		*/
		function GetNumberOfAttachments($QuestId)
		{
			// Workout how many attachments the selected question has
			$num = 0;
			$dir = sprintf("../attachments/%d", $QuestId);

			if (is_dir($dir)) {
				if ($dh = opendir($dir)) {
					while (($file = readdir($dh)) !== false) {
						if ($file != "." && $file != "..") {
							$num++;
						}
					}
					closedir($dh);
				}
			}
			return $num;
		}

		/**
		* DeleteQuestion
		* Delete a question from the database
		*
		* @return void
		*/
		function DeleteQuestion()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'delete')) {
				$this->NoPermission();
				return;
			}

			if (isset($_GET["questId"])) {
				$questId = $_GET["questId"];
				$query1 = sprintf("delete from %squestions where questionid='%d'", $GLOBALS["tablePrefix"], $questId);
				$query2 = sprintf("delete from %scategoryassociations where questionid='%d'", $GLOBALS["tablePrefix"], $questId);
				$query2 = sprintf("delete from %scatassoc_history where questionid='%d'", $GLOBALS["tablePrefix"], $questId);

				if ($GLOBALS['AKB_DB']->Query($query1) && $GLOBALS['AKB_DB']->Query($query2)) {
					$this->ShowQuestionList(GetLang("QuestionDeletedSuccessfully"), MSG_SUCCESS);
				} else {
					$this->ShowQuestionList();
				}
			} else {
				$this->ShowQuestionList();
			}
		}

		/**
		* ShowSubmittedQuestionList
		* Display the list of questions submitted through the contact form
		*
		* @param string $MsgDesc The message text
		* @param int $MsgStatus The type of message
		*
		* @return void
		*/
		function ShowSubmittedQuestionList($MsgDesc = "", $MsgStatus = "")
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'review')) {
				$this->NoPermission();
				return;
			}

			// Show a list of submitted questions
			$page = 0;
			$start = 0;
			$numQuestions = 0;
			$numPages = 0;
			$GLOBALS["QuestionGrid"] = "";
			$GLOBALS["Nav"] = "";
			$GLOBALS['HideHeading'] = '';
			$GLOBALS['BreadcrumEntries'] = array(GetLang("Home") => "index.php", GetLang("ReviewSubmittedQuestionsTitle") => "");
			$sortField = isset($_GET['sortField']) ? $_GET['sortField'] : 'subquestid';
			$sortOrder = isset($_GET['sortOrder']) ? $_GET['sortOrder'] : 'desc';
			$searchQuery = isset($_GET['searchQuery']) ? $_GET['searchQuery'] : '';
			$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;

			$sortURL = sprintf("&amp;sortField=%s&amp;sortOrder=%s", $sortField, $sortOrder);

			// Limit the number of questions returned
			$start = ($page == 1) ? 0 : ($page * AKB_QUEST_PER_PAGE) - (AKB_QUEST_PER_PAGE-1) -1;

			$questResult = $GLOBALS['AKB_DB']->Query("select count(*) from ".$GLOBALS['tablePrefix']."submittedquestions");
			$numQuestions = $GLOBALS['AKB_DB']->FetchOne($questResult);
			$numPages = ceil($numQuestions / AKB_QUEST_PER_PAGE);

			if ($MsgDesc != '') {
				$GLOBALS['Message'] = MessageBox($MsgDesc, $MsgStatus);
			}

			$GLOBALS['Nav'] = BuildNav('index.php?ToDo=reviewSubmittedQuestions', $numPages, $page);

			$GLOBALS["SearchQuery"] = $searchQuery;
			$GLOBALS["SortField"] = $sortField;
			$GLOBALS["SortOrder"] = $sortOrder;

			$GLOBALS["SubjectSortUpLink"] = sprintf("index.php?ToDo=reviewSubmittedQuestions&searchQuery=%s&amp;page=%d&amp;sortField=subject&amp;sortOrder=asc", $searchQuery, $page);
			$GLOBALS["SubjectSortDownLink"] = sprintf("index.php?ToDo=reviewSubmittedQuestions&amp;searchQuery=%s&amp;page=%d&amp;sortField=subject&amp;sortOrder=desc", $searchQuery, $page);

			$GLOBALS["DateSortUpLink"] = sprintf("index.php?ToDo=reviewSubmittedQuestions&searchQuery=%s&amp;page=%d&amp;sortField=posted&amp;sortOrder=asc", $searchQuery, $page);
			$GLOBALS["DateSortDownLink"] = sprintf("index.php?ToDo=reviewSubmittedQuestions&amp;searchQuery=%s&amp;page=%d&amp;sortField=posted&amp;sortOrder=desc", $searchQuery, $page);

			$query = sprintf("select sq.*, posted as datecreated from %ssubmittedquestions sq order by %s %s ".$GLOBALS['AKB_DB']->AddLimit($start, AKB_QUEST_PER_PAGE), $GLOBALS["tablePrefix"], $GLOBALS['AKB_DB']->Quote($sortField), $GLOBALS['AKB_DB']->Quote($sortOrder));
			$questResult = $GLOBALS['AKB_DB']->Query($query);

			if ($GLOBALS['AKB_DB']->CountResult($query) > 0) {
				while ($questRow = $GLOBALS['AKB_DB']->Fetch($questResult)) {
					$GLOBALS['QuestId'] = $questRow['subquestid'];

					if ($_SESSION['user']->verify('question', 'edit')) {
						$GLOBALS['PublishLink'] = '<a href="index.php?ToDo=createQuestion&submittedQuestId='.$questRow['subquestid'].'" class="bodylink">'.GetLang('Publish').'</a>';
					} else {
						$GLOBALS['PublishLink'] = '<span class="Disabled">'.GetLang('Publish').'</span>';
					}

					$GLOBALS['Subject'] = htmlspecialchars($questRow['subject'], ENT_QUOTES, $GLOBALS['charset']);
					$questRow['name'] = htmlspecialchars($questRow['name'], ENT_QUOTES, $GLOBALS['charset']);

					if ($questRow["email"] != "" && $questRow["name"] != "") {
						$GLOBALS["From"] = sprintf("<a href='mailto:%s'>%s</a>", $questRow["email"], $questRow["name"]);
					} else if ($questRow["email"] != "") {
						$GLOBALS["From"] = sprintf("<a href='mailto:%s'>%s</a>", $questRow["email"], $questRow["email"]);
					} else {
						$GLOBALS["From"] = $questRow["name"];
					}

					$GLOBALS['DateCreated'] 	= date("j F Y",strtotime($questRow["datecreated"]));
					$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("submittedquestion.row");
					$GLOBALS["QuestionGrid"] .= $GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate(true);
				}

				$GLOBALS['BreadcrumEntries'][GetLang("ReviewSubmittedQuestionsTitle")] = "";
				
				$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("submittedquestions.manage");
				$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
			} else {
				// There aren't any questions, show a message
				$GLOBALS["Title"] = GetLang("ReviewSubmittedQuestions");
				$GLOBALS["ButtonText"] = GetLang("CreateQuestion");
				$GLOBALS["ButtonClass"] = "Field150";
				$GLOBALS["Message"] = MessageBox(GetLang("NoSubmittedQuestions"), MSG_SUCCESS);
				$GLOBALS["URL"] = "index.php?ToDo=createQuestion";
				$GLOBALS['Style'] = '';

				$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("message");
				$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
			}
		}

		/**
		* PreviewSubmittedQuestion
		* Preview a submitted question in a popup window
		*
		* @return void
		*/
		function PreviewSubmittedQuestion()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'review')) {
				$this->NoPermission();
				return;
			}

			// Preview a question
			$query = "SELECT *
				FROM ".$GLOBALS['tablePrefix']."submittedquestions
				WHERE subquestid=".((int) $_GET['questId'])."";
			$result = $GLOBALS['AKB_DB']->Query($query);

			if ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$GLOBALS['Subject']	= htmlspecialchars($row['subject'], ENT_QUOTES, $GLOBALS['charset']);
				$GLOBALS['Message']	= htmlspecialchars($row['message'], ENT_QUOTES, $GLOBALS['charset']);
				$GLOBALS['From']	=PrepareCommentAuthor(htmlspecialchars($row['name'], ENT_QUOTES, $GLOBALS['charset']), $row['email']);

				$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("submittedquestion.preview");
				$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
				return true;
			}

			echo "<script type=\"text/javascript\" language=\"javascript\">window.close();</script>";
		}

		/**
		* DeleteSubmittedQuestion
		* Delete a submitted question from the database
		*
		* @return void
		*/
		function DeleteSubmittedQuestion()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'review')) {
				$this->NoPermission();
				return;
			}

			if (isset($_GET['questId'])) {
				$q = new API_SUBMITTEDQUESTION();

				if ($q->delete($_GET['questId'])) {
					$this->ShowSubmittedQuestionList(GetLang("QuestionDeletedSuccessfully"), MSG_SUCCESS);
				} else {
					$this->ShowSubmittedQuestionList();
				}
			} else {
				$this->ShowSubmittedQuestionList();
			}
		}

		/**
		* NotifySubmitterNewQuestion
		* Email the submitted of a question to let them know that their question
		* has been answered by the contents of a knowledge base article
		*
		* @param int $subquest The submitted question id
		*
		* @return void
		*/
		function NotifySubmitterNewQuestion($subquest, $questid)
		{
			if ($subquest->loaded) {
				$GLOBALS['name'] = $subquest->name;
				$GLOBALS['subject'] = $subquest->subject;
				$GLOBALS['link'] = GetUrl('question', $questid);
				$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('email.notifynewquestion');
				$body = $GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate(true);

				$email = new Email_API();
				setEmailVars($email);

				$email->Set('CharSet', $GLOBALS['charset']);
				$email->From($GLOBALS['contactEmail']);
				$email->Set('Subject', $subquest->subject);
				$email->AddBody('text', $body);
				$email->AddRecipient($subquest->email, '', 't');
				$email_result = $email->Send();
			}
		}

		/**
		* ViewHistory
		* View the previous versions of a question
		*
		* @return void
		*/
		function ViewHistory()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& !$_SESSION['user']->verify('question', 'delete')) {
				$this->NoPermission();
				return;
			}

			$GLOBALS['HistoryGrid'] = '';
			$GLOBALS['DateSortUpLink'] = '#';
			$GLOBALS['DateSortDownLink'] = '#';
			$GLOBALS['ImagePath'] = '../templates/' . $GLOBALS['template'] . '/Images';
			$GLOBALS['questionid'] = (int) $_GET['questionid'];
			$GLOBALS['ManageQuestionHistory'] = sprintf(GetLang('ManageQuestionHistory'), $GLOBALS['questionid']);
			

			if (isset($_GET['questionid']) && ((int) $_GET['questionid'] > 0)) {
				
				// check if the user has the permission to view the article's histor(ies)
				$qObj = new API_QUESTION();
				$qObj->load($_GET['questionid']);
				if (!$this->HasQuestionApprovalEditPerm($_GET['questionid'], $qObj->workflowstatus)) {
					$this->NoPermission();
					return false;
				}
				
				$query = "SELECT versionid, title, views, lastupdated, visible, posvotes, negvotes, username, firstname, lastname
					FROM `".$GLOBALS['tablePrefix']."questions_history` h LEFT OUTER JOIN `".$GLOBALS['tablePrefix']."users` u ON (u.userid = h.userid)
					WHERE questionid = ".$_GET['questionid']."
					ORDER BY lastupdated DESC";
				$result = $GLOBALS['AKB_DB']->Query($query);
				if ($GLOBALS['AKB_DB']->CountResult($query) > 0) {
					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.history.row');
					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						foreach ($row as $k => $v) {
							if ($k == 'views') {
								$GLOBALS[$k] = number_format($v);
							} else {
								$GLOBALS[$k] = $v;
							}
						}

						if ($row["visible"] == 0) {
							$GLOBALS["Visible"] = sprintf("<span style=\"margin-left:10px;\"><img border=\"0\" src=\"images/cross.gif\" alt=\"cross\"></span>", GetLang("QuestionVisibleTip"));
						} else {
							$GLOBALS["Visible"] = sprintf("<span style=\"margin-left:10px;\"><img border=\"0\" src=\"images/tick.gif\" alt=\"tick\"></span>", GetLang("QuestionInvisibleTip"));
						}

						if (trim($row['firstname']) != '' || trim($row['lastname']) != '') {
						
							$GLOBALS['Author'] = $row['firstname'].' '.$row['lastname'];
						} else {
							$GLOBALS['Author'] = $row['username'];
						}

						$posVotes = $row["posvotes"];
						$negVotes = $row["negvotes"];
						$votes = $posVotes + $negVotes;

						$voteString = ($votes == 1) ? GetLang("QuestVote") : GetLang("QuestVotes");

						if ($votes > 0) {
							$posPer = floor(($posVotes / $votes) * 100);
							$negPer = floor(($negVotes / $votes) * 100);

							if ($posPer > $negPer) {
								$output = sprintf("

									<span class=\"HighRate\">%d%%</span>
									<img src=\"%s/ThumbsUp.gif\" style=\"margin-right:10px\" alt=\"thumbsup\">
									<span class=\"LowRate\">%d%%</span>
									<img src=\"%s/ThumbsDown.gif\" style=\"margin-right:10px\" alt=\"thumbsdown\">
									<br />(%d %s)

								", $posPer, $GLOBALS["ImagePath"], $negPer, $GLOBALS["ImagePath"], $votes, $voteString);
							} else if ($posPer < $negPer) {
								$output = sprintf("

									<span class=\"LowRate\">%d%%</span>
									<img src=\"%s/ThumbsUp.gif\" style=\"margin-right:10px\" alt=\"thumbsup\">
									<span class=\"HighRate\">%d%%</span>
									<img src=\"%s/ThumbsDown.gif\" style=\"margin-right:10px\" alt=\"thumbsdown\">
									<br />(%d %s)

								", $posPer, $GLOBALS["ImagePath"], $negPer, $GLOBALS["ImagePath"], $votes, $voteString);
							} else {
								$output = sprintf("

									<span class=\"HighRate\">%d%%</span>
									<img src=\"%s/ThumbsUp.gif\" style=\"margin-right:10px\" alt=\"thumbsup\">
									<span class=\"HighRate\">%d%%</span>
									<img src=\"%s/ThumbsDown.gif\" style=\"margin-right:10px\" alt=\"thumbsdwon\">
									<br />(%d %s)

								", $posPer, $GLOBALS["ImagePath"], $negPer, $GLOBALS["ImagePath"], $votes, $voteString);
							}
						} else {
							$output = GetLang("QuestNoVotes");
						}
						$GLOBALS["Rating"] = $output;

						$GLOBALS['HistoryGrid'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate(true);
					}
					$q = new API_QUESTION;
					$GLOBALS['ManageQuestionHistoryIntro'] = sprintf(GetLang('ManageQuestionHistoryIntro'), $_GET['questionid']);

					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.history.manage');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				} else {
					$GLOBALS['Message'] = MessageBox(GetLang('firstVersion'), MSG_WARNING);
					$GLOBALS['HidePanels'][] = 'QuestionHistoryList';

					$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.history.manage');
					$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
				}
			}
		}

		/**
		* CopyAttachments
		* Copy Attachments from one articles to another
		* when an article is duplicated
		*
		* @param int $fromQuestionid The id of the source article
		* @param int $toQuestionid The id of the destination article
		*
		* @return void
		*/
		function CopyAttachments($fromQuestionid, $toQuestionid)
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			if (!is_numeric($fromQuestionid) || !is_numeric($toQuestionid)) {
				return false;
			}
			if (!is_dir($this->attachmentDirectory)) {
				return false;
			}
			if (!is_writeable($this->attachmentDirectory.DIRECTORY_SEPARATOR)) {
				return false;
			}

			$save_dir = $this->attachmentDirectory.DIRECTORY_SEPARATOR.$toQuestionid.DIRECTORY_SEPARATOR;
			if (!is_dir($save_dir)) {
				if (!mkdir($save_dir, 0777)) {
					return false;
				}
			}
			
			$source_dir = $this->attachmentDirectory.DIRECTORY_SEPARATOR.$fromQuestionid.DIRECTORY_SEPARATOR;
			if (!is_dir($source_dir)) {
				return false;
			}
			
			$fromAttachments = $this->GetAttachments($fromQuestionid);
			
			foreach ($fromAttachments as $fromAttachment) {
				$fromFile = $source_dir . $fromAttachment;
				$toFile = $save_dir . $fromAttachment;
				@copy($fromFile, $toFile);
				chmod($toFile, 0644);
			}
			
			// we skip the indexing process if we don't have attachment search enabled.
			if (!$GLOBALS['enableAttachmentSearch']) {
				return;
			}
			
			// Copy the content in pageindex across if it's exist & we enable search attachments.
			$attCopied = false;
			
			$query = "SELECT content, plugin, filename \n";
			$query .= "FROM ".$GLOBALS['tablePrefix']."pageindex \n";
			$query .= "WHERE questionid = '$fromQuestionid' \n";
			$result = $GLOBALS['AKB_DB']->Query($query);
			while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$attCopied = true;
    			$lastupdated = date("Y-m-d H:i:s");
    			$fullUrl = $GLOBALS['pathToKB'] . '/attachments/' . $toQuestionid . '/' . $row['filename'];
    			$query = "DELETE FROM ".$GLOBALS['tablePrefix']."pageindex WHERE questionid = '$toQuestionid' and filename = '{$row['filename']}'";
    			$GLOBALS['AKB_DB']->Query($query);
    			
    			$newData = array(
    			'fullurl' => $fullUrl, 
    			'questionid' => $toQuestionid, 
    			'content' => $row['content'], 
    			'plugin' => $row['plugin'], 
    			'filename' => $row['filename'], 
    			'lastupdated' => $lastupdated
    			);
    			$GLOBALS['AKB_DB']->InsertQuery($GLOBALS['tablePrefix'].'pageindex', $newData);
			}
			
			if ($attCopied) {
				if (isset($GLOBALS['enableFullindexPopulation']) && $GLOBALS['enableFullindexPopulation'] == true) {
					$GLOBALS['AKB_DB']->UpdateFullTextIndex (array($GLOBALS['tablePrefix'].'pageindex'), array($GLOBALS['tablePrefix'].'PI_FI_T', $GLOBALS['tablePrefix'].'PI_FI_A'));
				}
			}
		}
		
		
		/**
		* SaveAttachments
		* Save any uploaded attachment files to the right place when a question
		* is created or updated
		*
		* @param int $questionid The id of the question to associate the
		* attachments to
		*
		* @return void
		*/
		function SaveAttachments($questionid)
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			if (!is_numeric($questionid)) {
				return false;
			}
			if (!is_dir($this->attachmentDirectory)) {
				return false;
			}
			if (!is_array($_FILES)) {
				return false;
			}
			if (!is_writeable($this->attachmentDirectory.DIRECTORY_SEPARATOR)) {
				return false;
			}

			$save_dir = $this->attachmentDirectory.DIRECTORY_SEPARATOR.$questionid.DIRECTORY_SEPARATOR;
			if (!is_dir($save_dir)) {
				if (!mkdir($save_dir, 0777)) {
					return false;
				}
			}
			$attAdded = false;
			foreach ($_FILES as $f) {
				for ($i = 0; $i < count($f['name']); $i++) {
					if ($f["size"][$i] > 0) {
						// We have an attachment!
						move_uploaded_file($f["tmp_name"][$i], $save_dir.$f["name"][$i]);
						chmod($save_dir.$f["name"][$i], 0644);
						if (isset($GLOBALS['enableAttachmentSearch']) && $GLOBALS['enableAttachmentSearch']) {
							$attAdded = true;
							$extension = array_pop(explode(".", $f["name"][$i]));
							$validExtension = $GLOBALS['AKB_CLASS_FILEINDEX']->getValidExtension();
				    		if (isset($validExtension[$extension])) {
				    			// Create instance of needed plugin.
				    			$pluginName = $GLOBALS['AKB_CLASS_FILEINDEX']->getPlugin($extension);
				    			
				    			if ($pluginName) {
					    			$lastupdated = date("Y-m-d H:i:s");
					    			$fullUrl = $GLOBALS['pathToKB'] . '/attachments/' . $questionid . '/' . $f["name"][$i];
					    			$plugin = new $pluginName();
					    			$rawContent = getPage(str_replace(' ', '%20', $fullUrl));
					    			$attachmentContent = @$plugin->Parse($rawContent, $GLOBALS['pathToKB'] . '/attachments/');
					    			$attachmentContent = $GLOBALS['AKB_DB']->quote($attachmentContent);
					    			$attachmentContentCopy = '';
					    			
									if ($pluginName == 'External_Ppt_Plugin' || $pluginName == 'Pdf_Plugin') {
										$attachmentContentCopy = stripPluginHeader($attachmentContent);
									} else if ($pluginName == 'External_Doc_Plugin') {
										$attachmentContentCopy = str_replace('\r\n', ' ', $attachmentContent);
									}									
									
									if ($attachmentContentCopy != '') {
										$attachmentContent = $attachmentContentCopy;
									}
									
					    			$removeQuery = "DELETE FROM ".$GLOBALS['tablePrefix']."pageindex \n";
					    			$removeQuery .= "WHERE questionid = '$questionid' AND filename = '".$f["name"][$i]."' \n";
					    			$GLOBALS['AKB_DB']->Query($removeQuery);
					    			
					    			$newData = array(
					    			'fullurl' => $fullUrl, 
					    			'questionid' => $questionid, 
					    			'content' => $attachmentContent, 
					    			'plugin' => $pluginName, 
					    			'filename' => $f["name"][$i], 
					    			'lastupdated' => $lastupdated
					    			);
					    			$GLOBALS['AKB_DB']->InsertQuery($GLOBALS['tablePrefix'].'pageindex', $newData);
					    			
				    			}
				    		}
						}
					}
				}
			}
			if ($attAdded) {
				if (isset($GLOBALS['enableFullindexPopulation']) && $GLOBALS['enableFullindexPopulation'] == true) {
					$GLOBALS['AKB_DB']->UpdateFullTextIndex (array($GLOBALS['tablePrefix'].'pageindex'), array($GLOBALS['tablePrefix'].'PI_FI_T', $GLOBALS['tablePrefix'].'PI_FI_A'));
				}
			}
		}

		/**
		* Rollback
		*
		* Changes the question to a version saved in its history table
		*
		* @return void
		* @param questionid integer
		* @param versionid integer
		*/
		function Rollback($questionid, $versionid)
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			$question = new API_QUESTION();
			$question->load($questionid);
			if ($question->revert($versionid)) {
				$GLOBALS['Message'] = MessageBox(GetLang('rollbackOk') , MSG_SUCCESS);
			} else {
				$GLOBALS['Message'] = MessageBox(GetLang('rollbackProblem') , MSG_ERROR);
			}
		}

		/**
		* previewQuestionHistory
		* Preview a previous version of a question in a popup
		*
		* @param int $versionid The id of the version to preview
		*
		* @return void
		*/
		function previewQuestionHistory($versionid)
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')
			&& $_SESSION['user']->verify('question', 'delete')) {
				$this->NoPermission();
				return;
			}

			$query = "SELECT *
				FROM ".$GLOBALS['tablePrefix']."questions_history
				WHERE versionid=".((int) $versionid)."
				ORDER BY lastupdated";

			$result = $GLOBALS['AKB_DB']->Query($query);

			if ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$GLOBALS["Question"] = $row['title'];
				$GLOBALS["Answer"] = $row['answer'];
				$GLOBALS["AKB_CLASS_TEMPLATE"]->SetTemplate("question.preview");
				$GLOBALS["AKB_CLASS_TEMPLATE"]->ParseTemplate();
				return true;
			}
			echo '<script type="text/javascript" language="javascript">window.close()</script>';
		}

		/**
		* BuildListQueries
		*
		* Create the queries for displaying the list based on values saved in
		* the session. This function assumes that InitAdvancedSearch has been
		* called at some time in the sesison before it (not necessarily on this
		* page view).
		*
		* @return void
		*/
		function BuildListQueries($workflow = false, $includeDisapproved = true)
		{
			$page = isset($_GET['page'])? (int) $_GET['page'] : 1;
			$start = ($page == 1) ? 0 : ($page * AKB_QUEST_PER_PAGE) - (AKB_QUEST_PER_PAGE-1) -1;
			$questionExceptionQry = '';
			$approvalCatString = '';

			$allowedApprovalCats = $GLOBALS['AKB_CLASS_CATEGORY']->GetPermittedApprovalCats();
			If (AKB_AUTH::IsSuperAdmin()) {
				$allowedCats = $GLOBALS['AKB_CLASS_CATEGORY']->GetPermittedCats();
			} else {
				$allowedCats = ($workflow) ? $allowedApprovalCats : $GLOBALS['AKB_CLASS_CATEGORY']->GetPermittedCats();
			}
			
			if ($workflow) {
				$letter = 'wfletter';
			} else {
				$letter = 'letter';
			}
			
			if (!empty($allowedApprovalCats) && validUrl()) {
				$approvalCatString = implode(', ', $allowedApprovalCats);
				$questionException = array();
				$query = "SELECT q.questionid FROM %squestions q, %scategoryassociations a ";
				$query .= "WHERE q.questionid = a.questionid ";
				$query .= "AND a.categoryid IN (%s) ";
				$query .= "AND ( q.workflowstatus = '%s' OR q.workflowstatus = '%s' OR q.workflowstatus = '%s' )";
				$query = sprintf($query, $GLOBALS['tablePrefix'], $GLOBALS['tablePrefix'], $approvalCatString, WF_STATUS_PENDING, WF_STATUS_REPENDING, WF_STATUS_DISAPPROVED);
				
				$result = $GLOBALS['AKB_DB']->Query($query);
				while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					$questionException[] = $row['questionid'];
				}
				if (!empty($questionException)) {
				$questionExceptionQry = " AND q.questionid NOT IN ('" . implode("','", $questionException) . "')";
				}
			}

			$searching_in_cats = array();
			if (isset($_SESSION['search']['categories'])) {
				$searching_in_cats = array_diff($_SESSION['search']['categories'], array('-1'));
			}

			// Don't let users search in a category they don't have permission
			// to be looking in
			if (!empty($searching_in_cats) && $searching_in_cats[0] > 0) {
				$cats = array_intersect($allowedCats, $searching_in_cats);
			} else {
				$cats = $allowedCats;
			}
			if (empty($cats)) {
				$cats = array('-1');
			}

			// Start the query off
			if (empty($cats)) {
				$this->countQuery = "SELECT COUNT(*) FROM ";
			} else {
				// If we are restricting the view to some cats, add all the
				// child cats to the list
				foreach ($cats as $catid) {
					$GLOBALS['AKB_CLASS_CATEGORY']->getCatsInfo();
					if (!$workflow) {
						$cats = array_merge($cats, array_diff($GLOBALS['AKB_CLASS_CATEGORY']->tree->GetBranchFrom($catid, false), $cats));
					} else {
						$tempCat = array_diff($GLOBALS['AKB_CLASS_CATEGORY']->tree->GetBranchFrom($catid, false), $cats);
						foreach ($tempCat as $eachTempCat) {
							if (AKB_AUTH::HasApprovalAccess(array($eachTempCat), false, true)) {
								$cats[] = $eachTempCat;
							}
						}
					}
				}
				$this->countQuery = "SELECT COUNT(DISTINCT q.questionid) FROM ";
			}

			// includes the search for attachment content
			$attachmentQids = array();
			if (isset($GLOBALS['enableAttachmentSearch']) && $GLOBALS['enableAttachmentSearch'] == true && !empty($_SESSION['search']['q'])) {
				$tmpQuery = "SELECT DISTINCT pi.questionid FROM ".$GLOBALS['tablePrefix']."pageindex pi WHERE pi.content like '%".$_SESSION['search']['q']."%' OR pi.filename like '%".$_SESSION['search']['q']."%' ";
				$tmpResults = $GLOBALS['AKB_DB']->Query($tmpQuery);
				while ($tmpRow = $GLOBALS['AKB_DB']->Fetch($tmpResults)) {
					$attachmentQids[] = $tmpRow['questionid'];
				}
			}
			
			$this->query = "SELECT q.questionid as qid, q.questionid, title, workflowstatus, visible, views, ";
			$this->query .= "posvotes, negvotes, lastupdated, username, firstname, lastname, COUNT(co.commentid) as comments ";
			$this->query .= "\n";
			$this->query .= "FROM ";

			// Work out which tables we need
			if (empty($cats)) {
				$this->countQuery .= "`".$GLOBALS['tablePrefix']."questions` q ";
			} else {
				$this->countQuery .= "`".$GLOBALS['tablePrefix']."questions` q ";
				$this->countQuery .= " LEFT JOIN `".$GLOBALS['tablePrefix']."categoryassociations` a ON (q.questionid = a.questionid) \n";
			}

			$this->query .= "`".$GLOBALS['tablePrefix']."questions` q ";
			$this->query .= " LEFT OUTER JOIN `".$GLOBALS['tablePrefix']."users` u ON (q.userid = u.userid)";
			$this->query .= " LEFT OUTER JOIN `".$GLOBALS['tablePrefix']."comments` co ON (co.questionid = q.questionid)";
			if (!empty($cats)) {
				$this->query .= " LEFT OUTER JOIN `".$GLOBALS['tablePrefix']."categoryassociations` a ";
				$this->query .= "ON (a.questionid = q.questionid)\n";
			}

			$this->countQuery .= "WHERE (1=1)\n";
			$this->query .= " WHERE (1=1)\n";
			
			if (!empty($_SESSION['search']['q'])) {
				if (is_numeric($_SESSION['search']['q'])) {
					$this->countQuery .= " AND q.questionid = ".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['q'])." ";
					$this->query .= " AND q.questionid = ".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['q'])." ";
				} else {
					$this->countQuery .= " AND (title like '%".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['q'])."%'";
					$this->countQuery .= " OR answer like '%".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['q'])."%' ";
					$this->query .= " AND (title like '%".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['q'])."%'";
					$this->query .= " OR answer like '%".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['q'])."%' ";
					
					if (sizeof($attachmentQids)) {
						$this->countQuery .= " OR q.questionid in ('".implode("','", $attachmentQids)."') ";
						$this->query .= " OR q.questionid in ('".implode("','", $attachmentQids)."') ";
					}
					$this->countQuery .= " )\n";
					$this->query .= " )\n";
				}
			}

			if (!empty($cats)) {
				$catString = implode(', ', $cats);
				//Need to fork here. If we're specifying a category then we dont want to add the isnull check.
				if (((isset($_SESSION['search']['categories'])) && (is_array($_SESSION['search']['categories'])) && ($_SESSION['search']['categories'][0] > 0)) || 
				$workflow ) {
					$this->countQuery .= "AND (categoryid IN (".$catString."))\n";
					$this->query .= "AND (categoryid IN (".$catString."))\n";
				} else {
					$this->countQuery .= "AND ((categoryid IN (".$catString.") OR (categoryid IS NULL OR categoryid = 0))\n";
					$this->query .= "AND ((categoryid IN (".$catString.") OR (categoryid IS NULL OR categoryid = 0))\n";
					
					if (!empty($allowedApprovalCats)  && validUrl()) {
						$this->countQuery .= " OR (categoryid IN (".$approvalCatString.") AND (workflowstatus = '".WF_STATUS_APPROVED."' OR workflowstatus = '".WF_STATUS_AUTO_APPROVED."') )";
						$this->query .= " OR (categoryid IN (".$approvalCatString.") AND (workflowstatus = '".WF_STATUS_APPROVED."' OR workflowstatus = '".WF_STATUS_AUTO_APPROVED."') )";
					}
					$this->countQuery .= ")\n";
					$this->query .= ")\n";

				}
				
				if (!$workflow) {
					$this->countQuery .= "$questionExceptionQry\n";
					$this->query .= "$questionExceptionQry\n";
				}
			}

			$this->query .= "\n";
			$having = false;
			if (!empty($_SESSION['search']['viewedop'])
				&& !empty($_SESSION['search']['viewed'])
			) {
				$this->countQuery .= " AND views ".$_SESSION['search']['viewedop']." ".$_SESSION['search']['viewed']."\n";
				$this->query .= " AND views ".$_SESSION['search']['viewedop']." ".$_SESSION['search']['viewed']."\n";
				$having = true;
			}

			if (!empty($_SESSION['search']['workflowstatus']) && validUrl()) {
				if ($_SESSION['search']['workflowstatus'] != GetLang('AllStatuses')) {
					$qryString = " AND workflowstatus = '".$_SESSION['search']['workflowstatus']."'\n";
					if ($_SESSION['search']['workflowstatus'] == WF_STATUS_REPENDING || $_SESSION['search']['workflowstatus'] == WF_STATUS_PENDING) {
						$qryString = " AND (workflowstatus = '".WF_STATUS_PENDING."' OR workflowstatus = '".WF_STATUS_REPENDING."')\n";
					}
					$this->countQuery .= $qryString;
					$this->query .= $qryString;
					$having = true;
				}
			}

			if (!empty($_SESSION['search']['ratedop'])
				&& !empty($_SESSION['search']['rated'])
			) {
				if ($having) {
					$this->countQuery .= " AND posvotes/(posvotes+negvotes)*100 ".$_SESSION['search']['ratedop']." ".$_SESSION['search']['rated']."\n";
					$this->query .= " AND posvotes/(posvotes+negvotes)*100 ".$_SESSION['search']['ratedop']." ".$_SESSION['search']['rated']."\n";
				} else {
					$this->countQuery .= " AND posvotes/(posvotes+negvotes)*100 ".$_SESSION['search']['ratedop']." ".$_SESSION['search']['rated']."\n";
					$this->query .= " AND posvotes/(posvotes+negvotes)*100 ".$_SESSION['search']['ratedop']." ".$_SESSION['search']['rated']."\n";
					$having = true;
				}
			}

			if (!empty($_SESSION['search']['lastupdatedop'])
				&& !empty($_SESSION['search']['lastupdated'])
			) {
				if ($having) {
					$this->countQuery .= "AND lastupdated ".$_SESSION['search']['lastupdatedop']." '".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['lastupdated'])."'\n";
					$this->query .= "AND lastupdated ".$_SESSION['search']['lastupdatedop']." '".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['lastupdated'])."'\n";
				} else {
					$this->countQuery .= " AND lastupdated ".$_SESSION['search']['lastupdatedop']." '".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['lastupdated'])."'\n";
					$this->query .= "AND lastupdated ".$_SESSION['search']['lastupdatedop']." '".$GLOBALS['AKB_DB']->Quote($_SESSION['search']['lastupdated'])."'\n";
					$having = true;
				}
			}
			if (!empty($_SESSION['search'][$letter])) {
				
				$fromStartWith = $_SESSION['search'][$letter];
				$toStartWith = $_SESSION['search'][$letter];
				$startWithHelper = explode('-', $_SESSION['search'][$letter]);
				if (sizeof($startWithHelper) > 1) {
					$fromStartWith = $startWithHelper[0];
					$toStartWith = $startWithHelper[1];
				}
				
				if ($having) {
					$this->countQuery .= " AND ".$GLOBALS['AKB_DB']->SubString('title', 1, 1)." between '".$GLOBALS['AKB_DB']->Quote($fromStartWith)."' AND '".$GLOBALS['AKB_DB']->Quote($toStartWith)."'\n";
					$this->query .= " AND ".$GLOBALS['AKB_DB']->SubString('title', 1, 1)." between '".$GLOBALS['AKB_DB']->Quote($fromStartWith)."' AND '".$GLOBALS['AKB_DB']->Quote($toStartWith)."'\n";
				} else {
					$this->countQuery .= " AND ".$GLOBALS['AKB_DB']->SubString('title', 1, 1)." between '".$GLOBALS['AKB_DB']->Quote($fromStartWith)."' AND '".$GLOBALS['AKB_DB']->Quote($toStartWith)."'\n";
					$this->query .= " AND ".$GLOBALS['AKB_DB']->SubString('title', 1, 1)." between '".$GLOBALS['AKB_DB']->Quote($fromStartWith)."' AND '".$GLOBALS['AKB_DB']->Quote($toStartWith)."'\n";
					$having = true;
				}
			}

			if (isset($_SESSION['search']['visible']) && in_array($_SESSION['search']['visible'], array('yes', 'no'))) {
				$visible = ($_SESSION['search']['visible'] == 'yes') ? 1 : 0;
				if ($having) {
					$this->countQuery .= "AND visible = ".$visible."\n";
					$this->query .= "AND visible = ".$visible."\n";
				} else {
					$this->countQuery .= "AND visible = ".$visible."\n";
					$this->query .= "AND visible = ".$visible."\n";
					$having = true;
				}
			}
			
			if ($workflow && validUrl()) {
				$this->countQuery .= "AND (workflowstatus = '".WF_STATUS_REPENDING."' OR workflowstatus = '".WF_STATUS_PENDING."'";
				$this->query .= "AND (workflowstatus = '".WF_STATUS_REPENDING."' OR workflowstatus = '".WF_STATUS_PENDING."' ";
				if ($includeDisapproved) {
					$this->countQuery .=  " OR workflowstatus = '".WF_STATUS_DISAPPROVED."'";
					$this->query .=  " OR workflowstatus = '".WF_STATUS_DISAPPROVED."'";
				}
					$this->countQuery .=  ") \n";
					$this->query .=  ") \n";
				
			} else if (AKB_AUTH::IsSuperAdmin() && validUrl()) {
				$this->countQuery .= "AND (workflowstatus = '".WF_STATUS_APPROVED."' OR workflowstatus = '".WF_STATUS_AUTO_APPROVED."') \n";
				$this->query .= "AND (workflowstatus = '".WF_STATUS_APPROVED."' OR workflowstatus = '".WF_STATUS_AUTO_APPROVED."') \n";
			}

			if (isset($_SESSION['search']['featured']) && in_array($_SESSION['search']['featured'], array('yes', 'no'))) {
				$featured = ($_SESSION['search']['featured'] == 'yes') ? 1 : 0;
				if ($having) {
					$this->countQuery .= "AND featured = ".$featured."\n";
					$this->query .= "AND featured = ".$featured."\n";
				} else {
					$this->countQuery .= "AND featured = ".$featured."\n";
					$this->query .= "AND featured = ".$featured."\n";
					$having = true;
				}
			}

			$this->query .= "GROUP BY q.questionid, title, workflowstatus, visible, views, ";
			$this->query .= "posvotes, negvotes, lastupdated, username, firstname, lastname ";
			$this->query .= "\n";
									
			if (!isset($this->sortField)) {
				$this->sortField = $this->defaultTableSort;
			}

			if (!isset($this->sortDirection)) {
				$this->sortDirection = "DESC";
			}
			$this->query .= "ORDER BY ".$GLOBALS['AKB_DB']->Quote($this->sortField)." ".$GLOBALS['AKB_DB']->Quote($this->sortDirection)."\n";
			$this->query .= $GLOBALS['AKB_DB']->AddLimit($start, AKB_QUEST_PER_PAGE);
		}

		/**
		* AdvancedSearch
		*
		* Sets up the globals vars and parses the template to display the
		* advanced search page
		*
		* @return void
		*/
		function AdvancedSearch()
		{
			$applies = array();
			if (is_array($_SESSION['user']->groups) && !empty($_SESSION['user']->groups)) {
				foreach ($_SESSION['user']->groups as $group) {
					if (isset($group->applies['category']) && is_array($group->applies['category'])) {
						$applies = array_merge($applies, $group->applies['category']);
					}
				}
			}

			$this->InitAdvancedSearch();

			$GLOBALS['BreadcrumEntries'][GetLang("ManageQuestions")] = "index.php?ToDo=viewQuestions";
			$GLOBALS['BreadcrumEntries'][GetLang("AdvancedSearch")] = "";

			
			$GLOBALS['VisibleYesChecked']  = '';
			$GLOBALS['VisibleNoChecked'] = '';

			$GLOBALS['FeaturedYesChecked']  = '';
			$GLOBALS['FeaturedNoChecked'] = '';

			$GLOBALS['FormAction']		= $GLOBALS['pathToKB'].'/admin/index.php?ToDo=viewQuestions';
			$GLOBALS['CategoryOptions']	= $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions($_SESSION['search']['categories'], "<option %s value='%d'>%s</option>", "SELECTED", $Divider = "- ", $IncludeEmpty = true, $applies);
			
			$GLOBALS['ShowStatus'] = '';
			$GLOBALS['StatusOptions']	= $this->GetStatusOptions($_SESSION['search']['workflowstatus'], true);
			if (!validUrl()) {
				$GLOBALS['ShowStatus'] = 'display:none;';
				$GLOBALS['StatusOptions'] = '';
			}
			$GLOBALS['viewedOp']		= $GLOBALS['AKB_CLASS_HELPER']->getNumericCompareOptions($_SESSION['search']['viewedop']);
			$GLOBALS['lastupdatedOp']	= $GLOBALS['AKB_CLASS_HELPER']->getDateCompareOptions($_SESSION['search']['lastupdatedop']);
			$GLOBALS['ratedOp']			= $GLOBALS['AKB_CLASS_HELPER']->getNumericCompareOptions($_SESSION['search']['ratedop']);
			$GLOBALS['ratedBrackets']	= $GLOBALS['AKB_CLASS_HELPER']->getNumericBracketOptions($_SESSION['search']['rated']);
			$visible_checked = 'Visible'.ucfirst($_SESSION['search']['visible']).'Checked';
			$featured_checked = 'Featured'.ucfirst($_SESSION['search']['featured']).'Checked';
			$GLOBALS[$visible_checked] 	= 'checked';
			$GLOBALS[$featured_checked] 	= 'checked';

			$GLOBALS['viewed']		= $_SESSION['search']['viewed'];
			$GLOBALS['lastupdated']	= $_SESSION['search']['lastupdated'];
			$GLOBALS["SearchQuery"]	= $_SESSION['search']['q'];
			$GLOBALS["SortField"]	= $_SESSION['sort']['sortfield'];
			$GLOBALS["SortOrder"]	= $_SESSION['sort']['sortorder'];

			if (!empty($_SESSION['search']['lastupdated'])) {
				$GLOBALS['jsLastupdated'] = "'".str_replace("-", "','", $_SESSION['search']['lastupdated'])."'";
			} else {
				$GLOBALS['jsLastupdated'] = '';
			}

			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('advancedsearch');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}

		/**
		* WorkFlowAdvancedSearch
		*
		* Sets up the globals vars and parses the template to display the
		* advanced search page
		*
		* @return void
		*/
		function WorkFlowAdvancedSearch()
		{
			$applies = array();
			if (is_array($_SESSION['user']->groups) && !empty($_SESSION['user']->groups)) {
				foreach ($_SESSION['user']->groups as $group) {
					if (isset($group->applies['category']) && is_array($group->applies['category'])) {
						$applies = array_merge($applies, $group->applies['category']);
					}
				}
			}

			$this->InitAdvancedSearch();

			$GLOBALS['BreadcrumEntries'][GetLang("ManageWorkflowArticles")] = "index.php?ToDo=viewWorkflowQuestions";
			$GLOBALS['BreadcrumEntries'][GetLang("AdvancedSearch")] = "";
			
			$GLOBALS['VisibleYesChecked']  = '';
			$GLOBALS['VisibleNoChecked'] = '';

			$GLOBALS['FeaturedYesChecked']  = '';
			$GLOBALS['FeaturedNoChecked'] = '';

			$GLOBALS['FormAction']		= $GLOBALS['pathToKB'].'/admin/index.php?ToDo=viewWorkflowQuestions';
			$GLOBALS['CategoryOptions']	= $GLOBALS['AKB_CLASS_CATEGORY']->GetCategoryOptions($_SESSION['search']['categories'], "<option %s value='%d'>%s</option>", "SELECTED", $Divider = "- ", $IncludeEmpty = true,$workflow = true);
			
			$GLOBALS['ShowStatus'] = '';
			$GLOBALS['StatusOptions']	= $this->GetStatusOptions($_SESSION['search']['workflowstatus'], true);
			if (!validUrl()) {
				$GLOBALS['ShowStatus'] = 'display:none;';
				$GLOBALS['StatusOptions'] = '';
			}
			
			$GLOBALS['viewedOp']		= $GLOBALS['AKB_CLASS_HELPER']->getNumericCompareOptions($_SESSION['search']['viewedop']);
			$GLOBALS['lastupdatedOp']	= $GLOBALS['AKB_CLASS_HELPER']->getDateCompareOptions($_SESSION['search']['lastupdatedop']);
			$GLOBALS['ratedOp']			= $GLOBALS['AKB_CLASS_HELPER']->getNumericCompareOptions($_SESSION['search']['ratedop']);
			$GLOBALS['ratedBrackets']	= $GLOBALS['AKB_CLASS_HELPER']->getNumericBracketOptions($_SESSION['search']['rated']);
			$visible_checked = 'Visible'.ucfirst($_SESSION['search']['visible']).'Checked';
			$featured_checked = 'Featured'.ucfirst($_SESSION['search']['featured']).'Checked';
			$GLOBALS[$visible_checked] 	= 'checked';
			$GLOBALS[$featured_checked] 	= 'checked';

			$GLOBALS['viewed']		= $_SESSION['search']['viewed'];
			$GLOBALS['lastupdated']	= $_SESSION['search']['lastupdated'];
			$GLOBALS["SearchQuery"]	= $_SESSION['search']['q'];
			$GLOBALS["SortField"]	= $_SESSION['sort']['sortfield'];
			$GLOBALS["SortOrder"]	= $_SESSION['sort']['sortorder'];

			if (!empty($_SESSION['search']['lastupdated'])) {
				$GLOBALS['jsLastupdated'] = "'".str_replace("-", "','", $_SESSION['search']['lastupdated'])."'";
			} else {
				$GLOBALS['jsLastupdated'] = '';
			}

			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('advancedsearch');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}

		/**
		* InitAdvancedSearch
		*
		* Sets up the session vars to control searching and sorting for the page
		* that displays the list of questions.
		*
		* @return void
		*/
		function InitAdvancedSearch()
		{
			// Define the vars we want to keep track of related to searching
			// and sorting
			$search_settings = array (
				'q'				=> '',
				'categories'	=> array('-1'),
				'viewedop'		=> '>',
				'viewed'		=> '',
				'lastupdatedop'	=> '>=',
				'lastupdated'	=> '',
				'ratedop'		=> '>',
				'rated'			=> '',
				'visible'		=> 'both',
				'featured'		=> 'both',
				'letter'		=> '',
				'wfletter'		=> '',
				'workflowstatus'		=> '',
			);
			$sort_settings = array (
				'sortfield'		=> 'title',
				'sortorder'		=> 'asc',
			);

			if (isset($_GET['resetsearch'])) {
				unset($_SESSION['search']);
			}

			if (!isset($_SESSION['sort']['sortfield'])
				|| !isset($_SESSION['sort']['sortorder'])
				|| isset($_GET['sortfield'])
				|| isset($_GET['sortorder'])) {
				foreach ($sort_settings as $k => $v) {
					if (!empty($_GET) && isset($_GET[$k])) {
						$validate_function = 'validate_'.$k;
						if (method_exists($this, $validate_function)
							&& $this->$validate_function($_GET[$k])) {
							$_SESSION['sort'][$k] = $_GET[$k];
						} elseif (method_exists($this, $validate_function)) {
							$_SESSION['sort'][$k] = $v;
						} else {
							$_SESSION['sort'][$k] = $_GET[$k];
						}
					} else {
						$_SESSION['sort'][$k] = $v;
					}
				}
			}
			// If our search settings have never been saved or settings have
			// just been submitted then set them up, otherwise we assume they
			// are already set
			if (!isset($_SESSION['search'])
				|| isset($_POST['q'])
				|| !empty($_GET['letter'])
				|| !empty($_GET['wfletter'])
				) {
				foreach ($search_settings as $k => $v) {
					if (!empty($_REQUEST) && isset($_REQUEST[$k])) {
						// Only set the session var to the post var IF
						// the var doesnt have a validate function or if
						// the value passeds the validate function
						$validate_function = 'validate_'.$k;

						if (method_exists($this, $validate_function)
							&& $this->$validate_function($_REQUEST[$k])) {
								$_SESSION['search'][$k] = $_REQUEST[$k];
							} elseif (method_exists($this, $validate_function)) {
								$_SESSION['search'][$k] = $v;
							} else {
								$_SESSION['search'][$k] = $_REQUEST[$k];
							}
					} else {
						$_SESSION['search'][$k] = $v;
					}
				}
			}

			if (isset($_POST['q']) && ((isset($_POST['bulkaction']) && $_POST['bulkaction'] == '') || !isset($_POST['bulkaction']))) {
				$_SESSION['search']['searching'] = true;
			}
		}

		/**
		* SendSubscriberEmails
		*
		* Sends emails to subscribers when a question is updated
		*
		* @return void
		* @param questionid integer
		*/
		function SendSubscriberEmails($questionid=0)
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			if ($questionid <= 0) {
				return false;
			}

			if (!is_numeric($questionid)) {
				return false;
			}

			$query = "SELECT subscriberid, email, confirmcode, subscribedate, questionid
			FROM ".$GLOBALS['tablePrefix']."subscribers
			WHERE confirmed=1
			AND questionid=".$questionid;

			// If we have a low number of emails, just send them straight out
			$result = $GLOBALS['AKB_DB']->Query($query);
			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('email.subscribe');
			if ($GLOBALS['AKB_DB']->CountResult($query) <= SUBSCRIBER_EMAIL_THRESHOLD) {
				while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
					$GLOBALS['QuestionLink'] = GetUrl('question', $row['questionid'], '', false);
					$get = 'todo=__unsubscribe&id='.$row['subscriberid'].'&confirmcode='.$row['confirmcode'];
					$GLOBALS['UnsubscribeLink'] = GetUrl('question', $row['questionid'], $get, false);
					$GLOBALS['SubscribeDate'] = date('d-m-Y', strtotime($row['subscribedate']));
					$GLOBALS['QuestionTitle'] = $_POST['title'];

					$subject = GetLang('SubscribedQuestionUpdated');
					$body = $GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate(true);

					$email = new Email_API();
					setEmailVars($email);

					$email->Set('CharSet', $GLOBALS['charset']);
					$email->From($GLOBALS['contactEmail']);
					$email->Set('Subject', $subject);
					$email->AddBody('text', $body);
					$email->AddRecipient($row['email'], '', 't');
					$email_result = $email->Send();
				}
			}
		}

		// {{{ Import Questions
		/**
		* ImportQuestions
		*
		* Handles the process of importing questions into the database
		* @return void
		*/
		function ImportQuestions()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			if (!isset($_GET['step']) || !is_numeric($_GET['step'])) {
				$_GET['step'] = 1;
			}
			switch ($_GET['step']) {
				case 3:
					if ($this->ImportCheckStep2()) {
						$this->ImportStep3();
					} else {
						$this->ImportStep2();
					}
				break;
				case 2:
					if ($this->ImportCheckStep1()) {
						$this->ImportStep2();
					} else {
						$this->ImportStep1();
					}
				break;
				case 1:
				default:
					$this->ImportStep1();
			}
		}
		// }}}

		/**
		* ImportStep1
		*
		* processing: none
		* display: Choose the category to import into and find the file you
		* want to import also display a checekbox for if there are headers or
		* not
		* @return void
		*/
		function ImportStep1()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			$GLOBALS['CategoryList'] = $GLOBALS["AKB_CLASS_CATEGORY"]->GetCategoryOptions(0);
			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=importQuestions&amp;step=2';

			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.import.step1');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}

		/**
		* ImportCheckStep1
		*
		* Check that the data given at step1 is adequate for progress to step2
		* @return boolean True if its ok to proceed
		*/
		function ImportCheckStep1()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			if (!isset($_FILES['csvfile']) || $_FILES['csvfile']['size'] === 0) {
				$GLOBALS['Message'] = MessageBox('You need to upload a file', MSG_ERROR);
				return false;
			}

			if (!isset($_POST['category']) || !is_array($_POST['category'])) {
				$GLOBALS['Message'] = MessageBox(GetLang('ImportSelectCategory'), MSG_ERROR);
				return false;
			} else {
				$_SESSION['importCategories'] = $_POST['category'];
			}

			if (!isset($_POST['headers'])) {
				$_POST['headers'] = 0;
			}

			$_SESSION['importHeaders'] = $_POST['headers'];

			$srcfile = $_FILES['csvfile']['tmp_name'];
			$destfile = $this->importFile;

			return move_uploaded_file($srcfile, $destfile);
		}

		/**
		* ImportStep2
		*
		* processing: read the first line of the file and get the column names
		* or first row of data
		* display: a dialog allowing them to line up fields in the db with
		* fields in the csv
		* @return void
		*/
		function ImportStep2()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=importQuestions&amp;step=3';
			$GLOBALS['Grid'] = '';

			$fp = fopen($this->importFile, "r");
			if ($fp) {
				$fields = fgetcsv($fp, 1048576);
				fclose($fp);
			}

			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.import.step2.row');
			$i = 0;
			foreach ($this->importFields as $field) {
				$lngIndex = 'ImportLabel'.ucfirst($field);
				$GLOBALS['Label'] = $GLOBALS['AKB_LANG'][$lngIndex];
				$GLOBALS['SelectName'] = $field;
				if ($_SESSION['importHeaders'] == 1) {
					$GLOBALS['Options'] = $this->MakeOptions($fields, $field, false);
				} else {
					if (count($fields) >= count($this->importFields)) {
						$GLOBALS['Options'] = $this->MakeOptions($fields, $i, true);
					} else {
						$GLOBALS['Options'] = $this->MakeOptions($fields, $i, false);
					}
				}
				$GLOBALS['Grid'] .= $GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate(true);
				$i++;
			}

			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.import.step2');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}
		/**
		* ImportCheckStep2
		*
		* Check that the data given at step2 is adequate for progress to step3
		* @return boolean True if its ok to proceed
		*/
		function ImportCheckStep2()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			// We need at least 1 field linked up
			foreach ($_POST as $key => $val) {
				if (in_array($key, $this->importFields) && $val > -1) {
					return true;
				}
			}
			return false;
		}

		/**
		* ImportStep3
		*
		* process: import the entries
		* display: the world is peachy
		* @return void
		*/
		function ImportStep3()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=importQuestions&amp;step=4';
			$q = new API_QUESTION();
			$mapping = array();
			$GLOBALS['Success'] = 0;
			$GLOBALS['Failed'] = 0;
			$line = 1;
			$numfields = 0;

			foreach ($this->importFields as $val) {
				$mapping[$val] = $_POST[$val];
			}

			$fp = fopen($this->importFile, "r");
			if ($fp) {
				while (!feof($fp)) {
					$data = fgetcsv($fp, 1048576);

					// Skip blank lines
					if (empty($data) || (count($data) == 1 && empty($data[0]))) {
						$line++;
						continue;
					}

					// Skip the header line if there is one
					if ($line == 1 && $_SESSION['importHeaders'] == 1) {
						$line++;
						continue;
					}

					// Clear the information for the next rows import - we don't
					// want to accidently get information from the wrong source
					foreach ($q->fields as $field) {
						unset($_POST[$field]);
					}

					// Setup the data for importing
					foreach ($this->importFields as $field) {
						if (isset($mapping[$field]) && isset($data[$mapping[$field]])) {
							$_POST[$field] = $data[$mapping[$field]];
						}
					}

					// Set the defaults for any that arn't in the file
					foreach ($q->fields as $field) {
						if (!isset($_POST[$field])) {
							$_POST[$field] = $q->$field;
						}
					}
					// Hard code visible to 1 if its not set
					if (!isset($_POST['visible'])) {
						$_POST['visible'] = 1;
					}

					$_POST['startdate'] = "";
					$_POST['enableexpiry'] = "";
					$_POST['expirydate'] = "";

					// Set the userid to the currently logged in user
					$_POST['userid'] = $_SESSION['user']->userid;

					$newid = $q->create();

					if ($newid > 0) {
						$GLOBALS['Success']++;
						// Save the category associations
						foreach ($_SESSION['importCategories'] as $catid) {
							if ($catid > 0) {
								$query = sprintf("insert into %scategoryassociations(categoryid, questionid) values(%d, %d)", $GLOBALS["tablePrefix"], $catid, $newid);
								$query = sprintf("insert into %scatassoc_history(categoryid, questionid) values(%d, %d)", $GLOBALS["tablePrefix"], $catid, $newid);
								$GLOBALS['AKB_DB']->Query($query);
							}
						}
					} else {
						$failedLines[] = $line;
						$GLOBALS['Failed']++;
					}
					$line++;
				}
				fclose($fp);

				$GLOBALS['Failed'] = number_format($GLOBALS['Failed']);
				$GLOBALS['Success'] = number_format($GLOBALS['Success']);

				if (!empty($failedLines)) {
					$GLOBALS['Text'] = $GLOBALS['Failed'].' '.GetLang('QuestionsNotImportedSuccessfully')." -- ".$q->error;
					$GLOBALS['Href'] = 'index.php?ToDo=questionImportAnswers&data='.base64_encode($this->GetLinesFromFile($this->importFile, $failedLines));
					$GLOBALS['Height'] = '300';
					$GLOBALS['Width'] = '600';

					$GLOBALS['FailedListItem'] = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('LinkPopupWindow');
					$GLOBALS['Message'] = MessageBox(GetLang('QuestionImportError'), MSG_ERROR);
				} else {
					$GLOBALS['FailedListItem'] = $GLOBALS['Failed'].' '.GetLang('QuestionsNotImportedSuccessfully');
					$GLOBALS['Message'] = MessageBox(sprintf(GetLang('QuestionImportAllSuccess'), $GLOBALS['Success']), MSG_SUCCESS);
				}
			}
			if (isset($GLOBALS['enableFullindexPopulation']) && $GLOBALS['enableFullindexPopulation'] == true) {
				$GLOBALS['AKB_DB']->UpdateFullTextIndex(array($GLOBALS["tablePrefix"].'questions'), array($GLOBALS["tablePrefix"].'Q_FI_T', $GLOBALS["tablePrefix"].'Q_FI_A', $GLOBALS["tablePrefix"].'Q_FI_M'));
			}
			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.import.step3');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}

		/**
		* ShowImportErrors
		*
		* Show the page with the import errors on it
		*
		* @return void
		*/
		function ShowImportErrors()
		{
			// Check they have permission to be here
			if (!$_SESSION['user']->verify('question', 'edit')) {
				$this->NoPermission();
				return;
			}

			$GLOBALS['Errors'] = base64_decode($_GET['data']);
			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('question.import.errors');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}

		/**
		* MakeOptions
		*
		* Makes a string of html form options given an array of data used for
		* csv importing when we line up the fields
		*
		* @param array $data The first line of data from the csv file
		* @param string $field The field which is selected
		* @param bool $offset Is $field an offset in the data or the name of the
		* field
		*
		* @return string
		*
		*/
		function MakeOptions($data, $field, $offset=false)
		{
			if (!is_array($data)) {
				return '';
			}

			if (empty($data)) {
				return '';
			}

			$output = '<option value="-1">'.GetLang('DontLink').'</option>';

			foreach ($data as $key => $val) {
				if (!$offset && $field == $val) {
					$output .= '<option value="'.$key.'" selected>'.htmlspecialchars($val, ENT_QUOTES, $GLOBALS['charset']).'</option>';
				} else if ($offset && $field == $key) {
					$output .= '<option value="'.$key.'" selected>'.htmlspecialchars($val, ENT_QUOTES, $GLOBALS['charset']).'</option>';
				} else {
					$output .= '<option value="'.$key.'">'.htmlspecialchars($val, ENT_QUOTES, $GLOBALS['charset']).'</option>';
				}
			}
			return $output;
		}

		/**
		* validate_viewedop
		* Validate that the viewed op submitted is valid
		*
		* @param string $var The op to validate
		*
		* @return bool Is it valid ?
		*/
		function validate_viewedop($var)
		{
			$valid_ops = array ('>', '<', '=', '<=', '>=');
			return in_array($var, $valid_ops);
		}

		/**
		* validate_viewed
		* Validate that the viewed var is numeric
		*
		* @param int $var The value to validate
		*
		* @return bool Is it valid ?
		*/
		function validate_viewed($var)
		{
			return is_numeric($var);
		}

		/**
		* validate_lastupdatedop
		* Validate that the op submitted is valid
		*
		* @param $var The op to validate
		*
		* @return bool Is it valid ?
		*/
		function validate_lastupdatedop($var)
		{
			$valid_ops = array ('>=', '<=');
			return in_array($var, $valid_ops);
		}

		/**
		* validate_lastupdated
		* Validate that the value of last updated is valid
		*
		* @param string $var The date to check
		*
		* @return bool Is it valid ?
		*/
		function validate_lastupdated($var)
		{
			// Split the date into its parts
			$matches = array();
			preg_match('/^(\d{4})\-(\d{1,2})\-(\d{1,2})$/', $var, $matches);
			if (count($matches) <> 4) {
				return false;
			}
			$year = $matches[1];
			$month = $matches[2];
			$day = $matches[3];

			// Make sure the parts are ints
			if ((int) $year != $year) {
				return false;
			}
			if ((int) $month != $month) {
				return false;
			}
			if ((int) $day != $day) {
				return false;
			}

			// Make sure the month is valid
			if ($month > 12) {
				return false;
			}
			if ($month < 1) {
				return false;
			}

			// Make sure the day is valid
			if ($day < 1) {
				return false;
			}

			// Check the day to make sure its not bigger then that last of the month
			if ($day > date('t', mktime(0,0,0,$month,1,$year))) {
				return false;
			}
			return true;
		}

		/**
		* validate_ratedop
		* Check that the rated op is valid
		*
		* @param string $var The op to validate
		*
		* @return bool Is the op valid ?
		*/
		function validate_ratedop($var)
		{
			$valid_ops = array ('>', '<', '=', '<=', '>=');
			return in_array($var, $valid_ops);
		}

		/**
		* validate_rated
		* Validate that the value of rated is valid
		*
		* @param int $var The var to check
		*
		* @return bool Is it valid ?
		*/
		function validate_rated($var)
		{
			$valid_vals = array('0', '25', '50', '75', '100');
			return in_array($var, $valid_vals);
		}

		/**
		* validate_visible
		* Ensure the value of visible is valid
		*
		* @param string $var The value to check
		*
		* @return bool Is it valid ?
		*/
		function validate_visible($var)
		{
			$valid_vars = array('yes', 'no', 'both');
			return in_array($var, $valid_vars);
		}

		/**
		* validate_letter
		* Make sure the value is a valid letter or number
		*
		* @param string $var The value to check
		*
		* @return bool Is it valid ?
		*/
		function validate_letter($var)
		{
			$letters = GetAlphaList();
			return in_array(strtoupper($var), $letters);
		}

		/**
		* validate_sortorder
		* Ensure the sort order is valid
		*
		* @param The value to check
		*
		* @return bool Is it valid ?
		*/
		function validate_sortorder($var)
		{
			return ($var == 'asc' || $var == 'desc' || $var == '');
		}

		/**
		* validate_sortfield
		* Ensure the field the user wants to sort on is valid
		*
		* @param string $var the field to sort on
		*
		* @return bool Is it valid ?
		*/
		function validate_sortfield($var)
		{
			$valid_fields = array ('title', 'views', 'lastupdated', 'visible');
			return in_array($var, $valid_fields);
		}

		/**
		* GetLinesFromFile
		*
		* Get the given lines from the given file
		*
		* @param string $file The name of the file
		* @param array $lines The array of lines
		*
		* @return string The text of the lines
		*/
		function GetLinesFromFile($file, $lines)
		{
			if (empty($file)) {
				return '';
			}

			if (!is_array($lines)) {
				return '';
			}

			if (empty($lines)) {
				return '';
			}

			if (!file_exists($file)) {
				return '';
			}

			$line = 1;

			$text = '';

			$fp = fopen($file, 'r');
			if ($fp) {
				while (!feof($fp)) {
					if (in_array($line, $lines)) {
						$text .= fgets($fp, 1048576);
					} else {
						fgets($fp, 1048576);
					}

					$line++;
				}
			}

			return $text;
		}

		function getGroupsForSelect($selectedGroupsArray=false) {
			//Get the groups
			$group = new API_GROUP();
			$groups = $group->getList();

			if (!$selectedGroupsArray) {
				$selectedGroupsArray = array();
			}

			$groupsHTML = "";

			foreach ($groups as $id => $name) {
				$groupsHTML .= '<option value="'.$id.'"';
				$groupsHTML .= (in_array($id, $selectedGroupsArray)) ? ' selected="selected" ' : '';
				$groupsHTML .= '>'. htmlspecialchars($name, ENT_QUOTES, $GLOBALS['charset']);
				$groupsHTML .= "</option>\n";
			}

			return $groupsHTML;
		}

		function FormatAuthor($firstname,$lastname,$username) {
			if (trim($firstname) || trim($lastname)) {
				$authorStr = $firstname.' '.$lastname;
			} else {
				$authorStr = $username;
			}
			return htmlspecialchars($authorStr,ENT_QUOTES,$GLOBALS['charset']);
		}

		function ReturnPermissionsCell($qid, $status='') {
			$cellHTML = "";
			$status = encodeWorkflowStatus($status);
			if ($_SESSION['user']->verify('question', 'edit')) {
				$q = new API_QUESTION();
				if ($status == WF_STATUS_APPROVED || $status == WF_STATUS_AUTO_APPROVED || !validUrl() || ($q->get_owner($qid) == $_SESSION['user']->userid && isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && $status == WF_STATUS_DISAPPROVED && validUrl())) {
					$cellHTML .= '<a title="'.GetLang('EditHelp').'" href="index.php?ToDo=editQuestion&amp;questionid='.$qid.'">'.GetLang('Edit').'</a>&nbsp;';
					if (($q->get_owner($qid) == $_SESSION['user']->userid && isset($GLOBALS['allowsOwnerEditDisapprovedArticles']) && $GLOBALS['allowsOwnerEditDisapprovedArticles'] && $status == WF_STATUS_DISAPPROVED && validUrl())) {
						$cellHTML .= '<span class="Disabled" onclick="alert(\''.GetLang('NoArticleHistoryPermission').'\');">'.GetLang('History').'</span>&nbsp;';
						$cellHTML .= '<span class="Disabled" onclick="alert(\''.GetLang('NoArticleCopyPermission').'\');">'.GetLang('Copy').'</span>&nbsp;';
					} else {
						$cellHTML .= '<a title="'.GetLang('HistoryHelp').'" href="index.php?ToDo=viewQuestionHistory&amp;questionid='.$qid.'">'.GetLang('History').'</a>&nbsp;';
						$cellHTML .= '<a title="'.GetLang('CopyHelp').'" href="index.php?ToDo=copyQuestion&amp;questionid='.$qid.'">'.GetLang('Copy').'</a>&nbsp;';
					}
				} else {
					$cellHTML .= '<span class="Disabled" onclick="alert(\''.GetLang('NoArticleEditPermission').'\');">'.GetLang('Edit').'</span>&nbsp;';
					$cellHTML .= '<span class="Disabled" onclick="alert(\''.GetLang('NoArticleHistoryPermission').'\');">'.GetLang('History').'</span>&nbsp;';
					$cellHTML .= '<span class="Disabled" onclick="alert(\''.GetLang('NoArticleCopyPermission').'\');">'.GetLang('Copy').'</span>&nbsp;';
				}
			} else {
				$cellHTML .= '<span class="Disabled">'.GetLang('Edit').'</span>&nbsp;';
				$cellHTML .= '<span class="Disabled">'.GetLang('History').'</span>&nbsp;';
				$cellHTML .= '<span class="Disabled">'.GetLang('Copy').'</span>&nbsp;';
			}

			$cellHTML .= '<a title="'.GetLang('ViewHelp').'" href="'.GetUrl('question', $qid).'">'.GetLang('View').'</a>';

			return $cellHTML."&nbsp;&nbsp;";
		}

		function ReturnWorkflowPermissionsCell($qid, $status) {
			
			$cellHTML = "";
			if ($_SESSION['user']->verify('category', 'approve')) {
				$query = sprintf("SELECT count(versionid) as tot FROM %squestions_history WHERE questionid='%d'", $GLOBALS['tablePrefix'], $qid);
				$qhResult = $GLOBALS['AKB_DB']->Query($query);
				$tot = $GLOBALS['AKB_DB']->FetchOne($qhResult);
				
				$previewQuestionToolTip = GetLang('PreviewQuestionToolTip');
				$previewQuestionText = GetLang('ArticleViewChanges');
				$viewChanges = 0;

				$cellHTML .= '<a title="'.GetLang('EditHelp').'" href="index.php?ToDo=editQuestion&amp;questionid='.$qid.'">'.GetLang('Edit').'</a>&nbsp;';
				$cellHTML .= '<a title="'.GetLang('HistoryHelp').'" href="index.php?ToDo=viewQuestionHistory&amp;questionid='.$qid.'">'.GetLang('History').'</a>&nbsp;';
				if ($tot > 1) {
					$previewQuestionToolTip = GetLang('PreviewArticleChanges');
					$viewChanges = 1;
					$previewQuestionText = GetLang('ArticleViewChanges');
					$cellHTML .= '<a title="'.$previewQuestionToolTip.'" href="javascript:ShowArticlePreview('.$viewChanges.', '.$qid.');">'.$previewQuestionText.'</a>&nbsp;';
				} else {
					$cellHTML .= '<span class="Disabled">'.$previewQuestionText.'</span>&nbsp;';
				}

				if (strtolower($status) == WF_STATUS_APPROVED) {
					$cellHTML .= '<span class="Disabled">'.GetLang('Approve').'</span>&nbsp;';
				} else {
					$cellHTML .= '<a title="'.GetLang('ApproveHelp').'" href="javascript:ShowApprovalForm(\''.WF_STATUS_APPROVED.'\',0,'.$qid.');">'.GetLang('Approve').'</a>&nbsp;';
				}
				
				if (strtolower($status) == WF_STATUS_DISAPPROVED) {
					$cellHTML .= '<span class="Disabled">'.GetLang('Reject').'</span>&nbsp;';
				} else {
					$cellHTML .= '<a title="'.GetLang('RejectHelp').'" href="javascript:ShowApprovalForm(\''.WF_STATUS_DISAPPROVED.'\',0,'.$qid.');">'.GetLang('Reject').'</a>&nbsp;';
				}
			} else {
				$cellHTML .= '<span class="Disabled">'.GetLang('Edit').'</span>&nbsp;';
				$cellHTML .= '<span class="Disabled">'.GetLang('History').'</span>&nbsp;';
				$cellHTML .= '<span class="Disabled">'.GetLang('PreviewArticle').'</span>&nbsp;';
				$cellHTML .= '<span class="Disabled">'.GetLang('Approve').'</span>&nbsp;';
				$cellHTML .= '<span class="Disabled">'.GetLang('Reject').'</span>&nbsp;';
			}


			return $cellHTML."&nbsp;&nbsp;";
		}

		function ReturnWorkflowstatusCell($questionid,$workflowstatus) {
			$workflowstatus = decodeWorkflowStatus($workflowstatus);
			$workflowstatus = ucwords($workflowstatus);
			return trim($workflowstatus);
		}

		function ReturnVisibleCell($questionid,$visible) {
			if ($visible == 0) {
				if ($_SESSION['user']->verify('question', 'approve')) {
					$visibleHTML = sprintf('<a title="%s" href="index.php?ToDo=updateQuestionVisible&amp;questId=%d&amp;visible=1"><img border="0" src="images/cross.gif" alt="cross"></a>', GetLang('QuestionVisibleTip'), $questionid);
				} else {
					$visibleHTML = '<img border="0" src="images/cross.gif" alt="cross">';
				}
			} else {
				if ($_SESSION['user']->verify('question', 'approve')) {
					$visibleHTML = sprintf('<a title="%s" href="index.php?ToDo=updateQuestionVisible&amp;questId=%d&amp;visible=0"><img border="0" src="images/tick.gif" alt="tick"></a>', GetLang('QuestionInvisibleTip'), $questionid);
				} else {
					$visibleHTML = '<img border="0" src="images/tick.gif" alt="tick">';
				}
			}
			return "<span style=\"margin-left:10px;\">".$visibleHTML."</span>";
		}
		
		function ReturnWorkflowVisibleCell($questionid,$visible) {
			if ($visible == 0) {
				if ($_SESSION['user']->verify('question', 'approve')) {
					$visibleHTML = sprintf('<a title="%s" href="index.php?ToDo=updatePendingQuestionVisible&amp;questId=%d&amp;visible=1"><img border="0" src="images/cross.gif" alt="cross"></a>', GetLang('QuestionVisibleTip'), $questionid);
				} else {
					$visibleHTML = '<img border="0" src="images/cross.gif" alt="cross">';
				}
			} else {
				if ($_SESSION['user']->verify('question', 'approve')) {
					$visibleHTML = sprintf('<a title="%s" href="index.php?ToDo=updatePendingQuestionVisible&amp;questId=%d&amp;visible=0"><img border="0" src="images/tick.gif" alt="tick"></a>', GetLang('QuestionInvisibleTip'), $questionid);
				} else {
					$visibleHTML = '<img border="0" src="images/tick.gif" alt="tick">';
				}
			}

			return "<span style=\"padding-left:10px;\">".$visibleHTML."</span>";
		}
		
		function SendApprovalEmail() {
			$skipEmail = 1;
			if (isset($_REQUEST['sendButton'])) {
				$skipEmail = 0;
			}
			
			
			$GLOBALS['Message'] = MessageBox(GetLang('QuestionStatusUpdateFailed'), MSG_ERROR);
			if ($this->UpdateStatus($_REQUEST['questionIds'], $_REQUEST['status'], $_REQUEST['subject'], $_REQUEST['body'], $skipEmail)) {
				$GLOBALS['Message'] = MessageBox(GetLang('QuestionStatusUpdateSuccess'), MSG_SUCCESS);
			}
			$this->ShowWorkflowQuestionList();
		}
		
		function ShowApprovalEmailForm() {
			if (!isset($_GET['status']) || ( $_GET['status'] != WF_STATUS_APPROVED && $_GET['status'] != WF_STATUS_AUTO_APPROVED && $_GET['status'] != WF_STATUS_DISAPPROVED ) ) {
				return false;
			};
			$GLOBALS['questionIds'] = $_GET['questionIds'];
			$GLOBALS['status'] = $_GET['status'];
			$status = $_GET['status'];
			$GLOBALS['UpdateSuccess'] = MessageBox(GetLang('QuestionStatusUpdateSuccess'), MSG_SUCCESS);
			
			$sendButtonText = array(
				WF_STATUS_DISAPPROVED => sprintf(GetLang('DisapproveSend')),
				WF_STATUS_APPROVED => sprintf(GetLang('ApproveSend')),
				WF_STATUS_AUTO_APPROVED => sprintf(GetLang('ApproveSend'))
			);

			$skipButtonText = array(
				WF_STATUS_DISAPPROVED => sprintf(GetLang('DisapproveOnly')),
				WF_STATUS_APPROVED => sprintf(GetLang('ApproveOnly')),
				WF_STATUS_AUTO_APPROVED => sprintf(GetLang('ApproveOnly'))
			);

			
			$GLOBALS['SendButton'] = '<input name="sendButton" type="submit" value="'.$sendButtonText[$status].'" class="formbutton" style="width:110px">';
			$GLOBALS['SkipButton'] = '<input name="skipButton" type="submit" value="'.$skipButtonText[$status].'" class="formbutton" style="width:90px">';
			$GLOBALS['CalcelButton'] = '<input name="cancelButton" type="button" value="'.GetLang('Cancel').'" class="formbutton" onclick="if(confirm(\''.GetLang('CancelMessage').'\')){tb_remove();}">';			
			$message = array(
				WF_STATUS_DISAPPROVED => sprintf(GetLang('DisapprovalEmailHelp')),
				WF_STATUS_APPROVED => sprintf(GetLang('ApprovalEmailHelp')),
				WF_STATUS_AUTO_APPROVED => sprintf(GetLang('ApprovalEmailHelp'))
			);
			$subject = array(
				WF_STATUS_DISAPPROVED => sprintf(GetLang('ApprovalEmailSubject'), 'disapproved'),
				WF_STATUS_APPROVED => sprintf(GetLang('ApprovalEmailSubject'), 'approved'),
				WF_STATUS_AUTO_APPROVED => sprintf(GetLang('ApprovalEmailSubject'), 'approved')
			);
			
			$editLink = htmlentities($GLOBALS['pathToKB'] . '/index.php?ToDo=editQuestion&questionid=' . $GLOBALS['questionIds'], ENT_QUOTES, $GLOBALS['charset']);
			$body = array(
				WF_STATUS_DISAPPROVED => str_replace('{NL}', "\n", $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('DisapprovalEmailBody')),
				WF_STATUS_APPROVED => str_replace('{NL}', "\n", $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('ApprovalEmailBody')),
				WF_STATUS_AUTO_APPROVED => str_replace('{NL}', "\n", $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('ApprovalEmailBody'))
			);

			$GLOBALS['EmailToDisplay'] = 'display:none;';
			if (!strstr($GLOBALS['questionIds'], '_')) {
				$GLOBALS['EmailToDisplay'] = 'aaa';
				// Get the firstname lastname
				$q = new API_QUESTION();
				$q->load($GLOBALS['questionIds']);
				$a = new API_USER();
				$a->load($q->userid);
				
				// Get the display name of the author
				$displayName = $a->username;
				if ($a->firstname != '' || $a->lastname != '') {
					$displayName = trim($a->firstname . ' ' . $a->lastname);
				}
				
				// Get the email address of the author
				$displayEmail = GetLang('NA');
				if (trim($a->email) != '') {
					$displayEmail = $a->email;
				}
				
				$GLOBALS['ApprovalEmailTo'] = sprintf(GetLang('EmailToDisplay'), $displayName, $displayEmail);
				$GLOBALS[''] = $displayEmail;
			}
//				$editLink = htmlentities($GLOBALS['pathToKB'] . '/index.php?ToDo=editQuestion&questionid=' . $q->questionid, ENT_QUOTES, $GLOBALS['charset']);
			if (isset($_GET['a']) && $_GET['a'] == 1) {
				$GLOBALS['SendButton'] = '<input type="button" value="'.$sendButtonText[$status].'" class="formbutton" onclick="sendApprovalEmail(0);" style="width:110px">';
				$GLOBALS['SkipButton'] = '<input type="button" value="'.$skipButtonText[$status].'" class="formbutton" onclick="sendApprovalEmail(1);" style="width:90px">';
			}
			
			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=sendApprovalEmail';
			$GLOBALS['ApprovalEmailSubject'] = $subject[$status];
			$GLOBALS['ApprovalEmailBody'] = $body[$status];
			$GLOBALS['Message'] = $message[$status];
			$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('sendapprovalemail');
			$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
		}

	} // End class

	class QuestionManage_Table extends AKB_AdminTable {

		function QuestionManage_Table() {
			parent::AKB_AdminTable();
			
			$GLOBALS['TableIconImagePath'] = "images/article.gif";

			$this->prependDataTemplate['CHECKBOX'] = "admintable.cell.selector.check";
			$this->prependDataTemplate['ICON'] = "admintable.cell.selector.icon";

			$this->headingArray['qid'] 	= GetLang('QListHeaderId');
			$this->headingArray['title'] 		= GetLang('QListHeaderTitle');
			$this->headingArray['categories'] 	= GetLang('QListHeaderCategories');
			$this->headingArray['firstname']	= GetLang('QListHeaderAuthor');
			$this->headingArray['views'] 		= GetLang('QListHeaderViews');
			$this->headingArray['comments'] 	= GetLang('QListHeaderComments');
			$this->headingArray['ratings'] 		= GetLang('QListHeaderRatings');
			$this->headingArray['lastupdated'] 	= GetLang('QListHeaderLastUpdated');
		
			if (validUrl()) {		
				$this->headingArray['workflowstatus'] 	= GetLang('QListHeaderStatus');
				$this->addCallback("workflowstatus",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnWorkflowstatusCell"),array("__questionid__","__workflowstatus__"));
			}

			$this->headingArray['visible'] 		= GetLang('QListHeaderVisible');
			$this->headingArray['action'] 		= GetLang('QListHeaderAction');
			
			$this->sizeArray		= array("","20%","20%","","","","10%","","","");
			$this->prependDataID 	= "questionid";
			$this->tableIdent 		= "ShowQuestionsListRemote";

			$this->addCallback("unixdate",	"strtotime",array("__lastupdated__"));
			$this->addCallback("lastupdated","date",array("jS F Y","__unixdate__"));
			$this->addCallback("categories",array($GLOBALS['AKB_CLASS_CATEGORY'],"GetQuestionCategories"),array("__questionid__"));
			$this->addCallback("firstname",array($GLOBALS['AKB_CLASS_QUESTION'],"FormatAuthor"), array("__firstname__","__lastname__","__username__"));
			$this->addCallback("title","htmlspecialchars",array("__title__",ENT_QUOTES,$GLOBALS['charset']));

			$this->addCallback("comments", array($GLOBALS['AKB_CLASS_QUESTION'], "ReturnCommentCell"), array("__questionid__", "__comments__"));
			$this->addCallback("ratings",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnRatingCell"),array("__posvotes__","__negvotes__"));
			$this->addCallback("action",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnPermissionsCell"),array("__questionid__", "__workflowstatus__"));
			$this->addCallback("visible",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnVisibleCell"),array("__questionid__","__visible__"));

		}

		function ReturnTable() {
			return parent::ReturnTable();
		}
	}

	class QuestionWorkflowManage_Table extends AKB_AdminTable {

		function QuestionWorkflowManage_Table() {
			
			if (!validUrl()) {
				die();
			}
			
			parent::AKB_AdminTable();
			
			$GLOBALS['TableIconImagePath'] = "images/article.gif";

			$this->prependDataTemplate['CHECKBOX'] = "admintable.cell.selector.check";
			$this->prependDataTemplate['ICON'] = "admintable.cell.selector.icon";

			//TODO:: All these should be lang'd!!
			$this->headingArray['qid'] 	= GetLang('QListHeaderId');
			$this->headingArray['title'] 		= GetLang('QListHeaderTitle');
			$this->headingArray['categories'] 	= GetLang('QListHeaderCategories');
			$this->headingArray['firstname']	= GetLang('QListHeaderAuthor');
			$this->headingArray['lastupdated'] 	= GetLang('QListHeaderLastUpdated');
			$this->headingArray['workflowstatus'] 	= GetLang('QListHeaderStatus');
			$this->headingArray['visible'] 		= GetLang('QListHeaderVisible');
			$this->headingArray['action'] 		= GetLang('QListHeaderAction');

			$this->sizeArray		= array("","20%","20%","","","","10%","","","");
			$this->prependDataID 	= "questionid";
			$this->tableIdent 		= "ShowQuestionsListRemote";

			$this->addCallback("unixdate",	"strtotime",array("__lastupdated__"));
			$this->addCallback("lastupdated","date",array("jS F Y","__unixdate__"));
			$this->addCallback("categories",array($GLOBALS['AKB_CLASS_CATEGORY'],"GetQuestionCategories"),array("__questionid__"));
			$this->addCallback("firstname",array($GLOBALS['AKB_CLASS_QUESTION'],"FormatAuthor"), array("__firstname__","__lastname__","__username__"));
			$this->addCallback("title","htmlspecialchars",array("__title__",ENT_QUOTES,$GLOBALS['charset']));
			$this->addCallback("action",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnWorkflowPermissionsCell"),array("__questionid__", "__workflowstatus__"));
			$this->addCallback("workflowstatus",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnWorkflowstatusCell"),array("__questionid__","__workflowstatus__"));
			$this->addCallback("visible",array($GLOBALS['AKB_CLASS_QUESTION'],"ReturnWorkflowVisibleCell"),array("__questionid__","__visible__"));
		}

		function ReturnTable() {
			return parent::ReturnTable();
		}
	}

?>
